用实例告诉你该如何优化SQL

虽然现今硬件成本已经下降,通过升级硬件提升系统性能也是常用的优化方式。而实时性要求很高的系统,还是要从sql方面进行优化,今天我们从实例的出发,介绍该如何优化sql。

判断问题SQL

判断SQL是否有问题时可以通过两个表象进行判断:

系统级别表象

CPU消耗严重

IO等待严重

页面响应时间过长

应用的日志出现超时等错误

可以使用sar命令,top命令查看当前系统状态。也可以通过Prometheus、Grafana等监控工具观察系统状态。

640?wx_fmt=png

SQL语句表象

冗长

执行时间过长

从全表扫描获取数据

执行计划中的rows、cost很大

冗长的SQL都好理解,一段SQL太长阅读性肯定会差,而且出现问题的频率肯定会更高。更进一步判断SQL问题就得从执行计划入手,如下所示:

640?wx_fmt=png

执行计划告诉我们本次查询走了全表扫描Type=ALL,rows很大(9950400)基本可以判断这是一段”有味道”的SQL。

获取问题SQL

不同数据库有不同的获取方法,以下为目前主流数据库的慢查询SQL获取工具

MySQL

慢查询日志

测试工具loadrunner

Percona公司的ptquery等工具

Oracle

AWR报告

测试工具loadrunner等

相关内部视图如v$、$session_wait等

GRID CONTROL监控工具

达梦数据库

AWR报告

测试工具loadrunner等

达梦性能监控工具(dem)

相关内部视图如v$、$session_wait等

SQL编写技巧

SQL编写有以下几个通用的技巧:

• 合理使用索引

索引少了查询慢;索引多了占用空间大,执行增删改语句的时候需要动态维护索引,影响性能 选择率高(重复值少)且被where频繁引用需要建立B树索引;一般join列需要建立索引;复杂文档类型查询采用全文索引效率更好;索引的建立要在查询和DML性能之间取得平衡;复合索引创建时要注意基于非前导列查询的情况

• 使用UNION ALL替代UNION

UNION ALL的执行效率比UNION高,UNION执行时需要排重;UNION需要对数据进行排序

• 避免select * 写法

执行SQL时优化器需要将 * 转成具体的列;每次查询都要回表,不能走覆盖索引。

• JOIN字段建议建立索引

一般JOIN字段都提前加上索引

• 避免复杂SQL语句

提升可阅读性;避免慢查询的概率;可以转换成多个短查询,用业务端处理

你好星识 你好星识

你的全能AI工作空间

你好星识 40 查看详情 你好星识

• 避免where 1=1写法

• 避免order by rand()类似写法

RAND()导致数据列被多次扫描

SQL优化

执行计划

完成SQL优化一定要先读执行计划,执行计划会告诉你哪些地方效率低,哪里可以需要优化。我们以MYSQL为例,看看执行计划是什么。(每个数据库的执行计划都不一样,需要自行了解)

640?wx_fmt=png

字段 解释

id每个被独立执行的操作标识,标识对象被操作的顺序,id值越大,先被执行,如果相同,执行顺序从上到下select_type查询中每个select 字句的类型table被操作的对象名称,通常是表名,但有其他格式partitions匹配的分区信息(对于非分区表值为NULL)type连接操作的类型possible_keys可能用到的索引key优化器实际使用的索引(最重要的列) 从最好到最差的连接类型为const、eq_reg、ref、range、index和ALL。当出现ALL时表示当前SQL出现了“坏味道”key_len被优化器选定的索引键长度,单位是字节ref表示本行被操作对象的参照对象,无参照对象为NULLrows查询执行所扫描的元组个数(对于innodb,此值为估计值)filtered条件表上数据被过滤的元组个数百分比extra执行计划的重要补充信息,当此列出现Using filesort , Using temporary 字样时就要小心了,很可能SQL语句需要优化

接下来我们用一段实际优化案例来说明SQL优化的过程及优化技巧。

优化案例

表结构

CREATE TABLE `a`(    `id`          int(11) NOT NULLAUTO_INCREMENT,    `seller_id`   bigint(20)                                       DEFAULT NULL,    `seller_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,    `gmt_create`  varchar(30)                                      DEFAULT NULL,    PRIMARY KEY (`id`));CREATE TABLE `b`(    `id`          int(11) NOT NULLAUTO_INCREMENT,    `seller_name` varchar(100) DEFAULT NULL,    `user_id`     varchar(50)  DEFAULT NULL,    `user_name`   varchar(100) DEFAULT NULL,    `sales`       bigint(20)   DEFAULT NULL,    `gmt_create`  varchar(30)  DEFAULT NULL,    PRIMARY KEY (`id`));CREATE TABLE `c`(    `id`         int(11) NOT NULLAUTO_INCREMENT,    `user_id`    varchar(50)  DEFAULT NULL,    `order_id`   varchar(100) DEFAULT NULL,    `state`      bigint(20)   DEFAULT NULL,    `gmt_create` varchar(30)  DEFAULT NULL,    PRIMARY KEY (`id`));

三张表关联,查询当前用户在当前时间前后10个小时的订单情况,并根据订单创建时间升序排列,具体SQL如下

select a.seller_id,       a.seller_name,       b.user_name,       c.statefrom a,     b,     cwhere a.seller_name = b.seller_name  and b.user_id = c.user_id  and c.user_id = 17  and a.gmt_create    BETWEEN DATE_ADD(NOW(), INTERVAL – 600 MINUTE)    AND DATE_ADD(NOW(), INTERVAL 600 MINUTE)order by a.gmt_create;

查看数据量  

aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9FbnpBd3ZwVFFKNzY5TTZaaWNvbjRWVGdpY2FMdTNyN0s2R2lhY21zTjgySE1JZFh5aWJWWjFOZmhmeUxJOGlhWUl4SU54UFdxa1Nsalh5UFlxSHJOMVU2MWljUS82NDA_d3hfZm10PXBuZw.png

原执行时间

aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9FbnpBd3ZwVFFKNzY5TTZaaWNvbjRWVGdpY2FMdTNyN0s2M0pydlYyMlNWbENuRU1HZm1jSXBxaWNOWGliV2I4elBVbjdLMUVURnIzNWNXdmliQWYzQUlDRjV3LzY0MD93eF9mbXQ9cG5n.png

原执行计划

640?wx_fmt=png

初步优化思路

SQL中 where条件字段类型要跟表结构一致,表中     user_id 为varchar(50)类型,实际SQL用的int类型,存在隐式转换,也未添加索引。将b和c表     user_id 字段改成int类型。

因存在b表和c表关联,将b和c表     user_id创建索引

因存在a表和b表关联,将a和b表     seller_name字段创建索引

利用复合索引消除临时表和排序

初步优化SQL

alter table b modify `user_id` int(10) DEFAULT NULL;alter table c modify `user_id` int(10) DEFAULT NULL;alter table c add index `idx_user_id`(`user_id`);alter table b add index `idx_user_id_sell_name`(`user_id`,`seller_name`);alter table a add index `idx_sellname_gmt_sellid`(`gmt_create`,`seller_name`,`seller_id`);

 查看优化后执行时间

aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9FbnpBd3ZwVFFKNzY5TTZaaWNvbjRWVGdpY2FMdTNyN0s2empYMm04ZG4yUDZvbXNTZkwxSFg2UFZKVlVjQUlsR1ZzSTB5cWw1ZWJNdTZIaGROV292aWJSQS82NDA_d3hfZm10PXBuZw.png

查看优化后执行计划

640?wx_fmt=png

查看warnings信息

640?wx_fmt=png

继续优化alter table a modify “gmt_create” datetime DEFAULT NULL;

查看执行时间

aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9FbnpBd3ZwVFFKNzY5TTZaaWNvbjRWVGdpY2FMdTNyN0s2UUFNcHh4TzI5R0huOEwxbmhYbmJTc2JBOFRHa2ljY1dpYVBsS3ptNWhLb1k3Q1RpYVRWU1o3U0ZnLzY0MD93eF9mbXQ9cG5n.png

查看执行计划

640?wx_fmt=png

总结

查看执行计划 explain

如果有告警信息,查看告警信息 show warnings;

查看SQL涉及的表结构和索引信息

根据执行计划,思考可能的优化点

按照可能的优化点执行表结构变更、增加索引、SQL改写等操作

查看优化后的执行时间和执行计划

如果优化效果不明显,重复第四步操作

相关推荐:《mysql教程》

以上就是用实例告诉你该如何优化SQL的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/289873.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月4日 20:07:20
下一篇 2025年11月4日 20:10:55

相关推荐

  • MySQL怎样优化SQL语句 MySQL高效SQL语句编写的技巧与规范

    mysql优化sql语句的核心是提升查询速度并减少资源消耗,需通过索引优化、查询结构改进和配置调优等多方面协同实现。1. 索引优化:应根据查询类型选择合适的索引(如b-tree用于范围查询,hash用于等值查询),在where、order by、group by涉及的列上创建索引,优先为高选择性列建…

    2025年12月5日
    000
  • ThinkPHP的模型是什么?ThinkPHP如何定义数据模型?

    thinkphp的模型是对数据库表的面向对象抽象,用于简化数据库操作。它通过定义继承自model的类,实现对数据表的映射,支持自动验证、自动完成、关联模型和数据缓存等高级功能。1. 模型分为基础模型、高级模型和空模型三种类型;2. 使用模型时可通过create()和add()方法实现数据验证与插入;…

    2025年12月5日 PHP框架
    000
  • MySQL网络延迟性能优化_MySQL减少响应时间方法

    mysql网络延迟问题可通过多层面诊断与优化解决。1.诊断需从网络、mysql状态、数据包分析及系统资源四方面入手;2.调整tcp_nodelay、socket_buffer_size、max_allowed_packet等参数;3.使用连接池、长连接、查询缓存减少连接开销;4.sql优化包括精简字…

    2025年12月4日 数据库
    000
  • YII框架的分库分表是什么?YII框架如何支持大数据量?

    yii框架本身不内置分库分表功能,但通过灵活的数据库配置和activerecord扩展支持分库分表实现;1. 可通过配置多个db组件并重写activerecord的getdb()方法实现动态数据库路由;2. 使用缓存机制、sql优化、读写分离和连接池管理提升大数据量下的性能;3. 跨库查询可通过应用…

    2025年12月4日
    000
  • mysql如何查看表的索引顺序 mysql表索引字段顺序查看教程

    要查看mysql表的索引字段顺序,最直接的方法是使用show index from your_table_name命令或查询information_schema.statistics表,其中seq_in_index字段明确指示了各字段在索引中的排列顺序,从1开始递增,通过这两种方式可清晰了解复合索引…

    2025年12月3日
    000
  • Swoole如何处理连接池满?池满策略有哪些?

    %ignore_a_1%满时需根据应用需求选择阻塞、抛出异常或拒绝连接策略;监控连接池状态可借助Swoole API结合Prometheus,及时发现瓶颈;调整连接池大小应基于并发量、资源和业务复杂度,避免过大或过小;优化策略包括连接预热、超时控制、复用、健康检查、异步操作和SQL优化;避免死锁需防…

    2025年12月3日
    800
  • SQL中IS NOT NULL的查询优化 IS NOT NULL条件查询的性能提升方法

    is not null查询通常较慢,优化方法包括使用覆盖索引、过滤索引和普通索引进行索引优化;通过union all拆分查询、避免在where子句中使用函数以及使用case语句进行查询重写;并通过避免null值、使用not null约束或单独存储null值调整数据模型。1. 索引优化方面,优先使用覆…

    2025年12月3日 数据库
    000
  • SQL子查询如何优化 子查询优化的4个有效方法

    sql子查询优化的核心在于避免全表扫描和重复处理,主要方法包括1.改写为连接查询以减少中间结果;2.合理使用索引加速检索;3.优先使用非相关子查询;4.避免在循环中执行子查询。执行计划和慢查询日志可用于判断是否需要优化,改写时需注意数据一致性及连接类型选择,索引应建在查询条件或连接字段上,并定期维护…

    2025年12月3日 数据库
    000
  • SQL中如何优化表的存储引擎以提高性能

    如何选择和优化%ignore_a_1%?根据应用场景选择合适的存储引擎,并通过配置和维护优化性能。1.选择innodb处理高并发事务,myisam提升查询性能。2.优化innodb时,调整缓冲池大小和日志文件大小。3.优化myisam时,使用全文索引。4.定期维护表以提高性能。 在SQL中,选择合适…

    2025年12月3日 数据库
    000
  • sql中如何分析执行计划 执行计划解读与优化建议

    sql执行计划是数据库用于展示sql语句执行方式的工具,理解它有助于发现性能瓶颈并优化查询效率。1. 查看执行计划的方法因数据库而异:mysql和postgresql使用explain关键字;sql server可用ssms或set showplan_all on;oracle通过explain p…

    2025年12月3日 数据库
    000
  • SQL执行计划解读 SQL查询分析优化教程

    sql执行计划是数据库优化的关键工具,用于诊断查询性能问题。1.掌握获取执行计划的方法:mysql用explain,postgresql用explain或explain analyze,sql server用showplan设置或图形界面,oracle用explain plan配合dbms_xpla…

    2025年12月3日 数据库
    000
  • AI运行MySQL语句的方法是什么_使用AI操作MySQL数据库指南

    AI操作MySQL需将自然语言转为SQL,依赖LLM理解用户意图并结合数据库Schema生成查询,通过API或本地模型执行。典型流程包括:用户输入自然语言指令,AI解析关键信息,匹配数据库结构,生成SQL语句(如多表JOIN、聚合查询),经语法检查与优化后,通过安全连接执行并返回结果。为确保准确性,…

    2025年12月3日 数据库
    000
  • SQL连续登录查询怎么建索引_SQL优化连续登录查询索引策略

    答案:SQL连续登录查询的索引策略需在user_id和login_time上创建复合索引,并结合分区、预计算和窗口函数优化性能,针对大规模数据可采用按时间分区或预计算连续天数以提升效率。 SQL连续登录查询的索引策略关键在于如何高效地定位到用户的登录记录,并快速判断是否满足连续登录的条件。核心在于选…

    2025年12月3日 数据库
    000
  • 使用AI执行SQL空间查询的方法_AI处理地理空间数据指南

    AI通过大语言模型将自然语言转化为含空间函数的SQL,实现非专业用户与地理空间数据库的高效交互。系统需完成意图捕获、语义解析、模式理解、函数映射与SQL生成,并依赖精准的数据库上下文、高质量Prompt、少量样本学习及人工反馈提升准确性;同时通过利用空间索引、避免N+1查询、引入优化器与缓存机制保障…

    2025年12月3日 数据库
    000
  • 怎么教AI理解并执行SQL命令_训练AI正确运行SQL语句教程

    答案是通过结合NLP、语义解析与模型迭代,利用高质量“问题-SQL”对和数据库schema训练基于Transformer的模型,并引入执行反馈与错误分析来提升AI生成SQL的准确性与效率。 教AI理解并执行SQL命令,核心在于将其自然语言输入转化为结构化的查询语言,这通常通过结合自然语言处理(NLP…

    2025年12月3日 数据库
    000
  • AI执行聚合函数SQL的方法_使用AI处理GROUPBY查询教程

    AI能将自然语言转化为SQL聚合查询,通过意图识别、实体链接和模式匹配,结合数据库结构生成准确的GROUP BY语句,同时提供查询优化、错误检测和跨数据库转换等能力,显著提升开发效率与查询性能,但需应对幻觉、数据安全及模型通用性等挑战。 AI,特别是那些大型语言模型,在处理SQL聚合函数和 GROU…

    2025年12月3日 数据库
    000
  • SQL连续登录解法有哪些常见错误_SQL解连续登录常见误区

    答案是明确“连续登录”的业务定义并结合SQL优化策略。首先需与业务方确认时间单位、去重规则和间隔阈值,再通过去重预处理和窗口函数(如ROW_NUMBER、LAG)或分组标识法识别连续行为,最后借助索引、数据过滤、物化视图等手段提升海量数据下的查询效率。 在处理SQL连续登录这类问题时,我发现很多开发…

    2025年12月3日 数据库
    000
  • AI自动优化SQL语句的方法是什么_AI优化与执行SQL代码流程

    AI自动优化SQL是通过语义分析、机器学习与强化学习技术,对SQL语句进行查询改写、索引推荐、执行计划预测、参数调优等多阶段智能迭代优化,结合历史数据与实时环境构建闭环工作流,在提升查询性能的同时面临上下文理解、模型更新、可解释性等挑战,需人机协同实现最佳效果。 AI自动优化SQL语句,说到底,就是…

    2025年12月3日 数据库
    000
  • SQLSUM函数带条件求和怎么写_SQLSUM条件求和CASE用法

    SQL中要实现带条件求和,最核心且普遍适用的方法就是将 SUM 函数与 CASE WHEN 表达式巧妙地结合起来。这种组合允许你在聚合过程中,根据你定义的各种条件,灵活地决定哪些值应该被纳入求和,哪些应该被忽略或替换为零,从而实现非常精细化的数据统计。 解决方案 说实话,当我第一次接触到需要“条件求…

    2025年12月3日 数据库
    000
  • 如何用AI执行SQL性能调优_AI分析与优化SQL执行计划

    AI通过分析SQL执行计划图结构与历史性能数据,利用机器学习识别全表扫描、低效连接等瓶颈,推荐索引优化、查询重写、参数调整等策略,并持续迭代提升数据库效率。 AI在SQL性能调优中,特别是对SQL执行计划的分析与优化,正逐渐展现出颠覆性的潜力。它能通过机器学习模型,自动识别执行计划中的效率瓶颈,并智…

    2025年12月3日 数据库
    000

发表回复

登录后才能评论
关注微信