SQL 越写越慢?一条慢查询排查清单(含 EXPLAIN 图解)

简介: 慢 SQL 是数据库性能问题中最常见的元凶。本文给出一份可直接照做的排查清单:三步定位问题 SQL、读懂 EXPLAIN 的关键字段、常见索引失效场景与修法、深分页优化与覆盖索引,并沉淀一套慢查询治理机制与上线自检清单,适合后端工程师与 DBA 对照实践。

SQL 越写越慢?一条慢查询排查清单(含 EXPLAIN 图解)

导读:这是一份可直接照做的慢 SQL 排查清单:①先用三步定位问题 SQL;②学会读懂 EXPLAIN 的关键字段;③常见索引失效场景与分页优化写法。适合后端工程师、DBA 和所有写业务 SQL 的开发者。

一、先定位:三步找到问题 SQL

1.1 打开慢查询日志

MySQL 开启慢查询日志,把执行超过阈值(建议 1s)的 SQL 记录下来:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = ON;

说明:log_queries_not_using_indexes 会把没走索引的查询也记下来,这类"扫描全表"的问题往往比"慢但走了索引"更值得优先处理。

1.2 看监控趋势

慢 SQL 数量是否在涨、集中在哪个时间段、是否与某次发版/数据量增长重合。先看趋势再动手,避免在偶发抖动上过度优化。

1.3 抓主谋

同一时间慢 SQL 往往不止一条,按"出现次数 × 单次耗时"排序,优先处理累计消耗最大的几条,而不是最慢的那一条。

1.4 把慢 SQL 变成"可复盘资产"

每次排查结束后,把问题 SQL、根因、修法记成一条记录(库名、表名、执行计划、修复前后耗时对比)。坚持一个月,你会得到一份"本业务专属的慢查询黑名单",新同学接手时直接照表排查,而不是重新踩一遍坑。

二、读懂 EXPLAIN:五个关键字段

对目标 SQL 执行 EXPLAIN,重点看五列:

字段 含义 危险信号
type 访问类型 ALL(全表扫描)最危险
key 实际使用的索引 NULL = 没走索引
rows 预估扫描行数 远大于实际返回行数
extra 附加信息 出现 filesort/temporary 要警惕
possible_keys 可能用到的索引 有候选但没用上 = 索引没建对
EXPLAIN SELECT order_no, amount FROM orders WHERE status = 2 AND created_at > '2026-09-01';

输出里如果 type=ALL 且 rows 是百万级,基本可以断定:这条 SQL 在扫全表。

经验值:type 至少要到 ref 或 range;rows 目标控制在万级以内;出现 filesort 时优先看能否用索引排序消除。

三、高频慢查询根因与修法

3.1 索引失效的常见场景

场景 示例 修法
列上做函数/计算 WHERE YEAR(created_at)=2026 改成范围查询 created_at >= '2026-01-01'
隐式类型转换 字符串列查数字 参数与列类型保持一致
前导模糊匹配 LIKE '%关键词' 改为前缀匹配或上全文索引/搜索引擎
OR 连接多个条件 WHERE a=1 OR b=2 拆成 UNION 或建联合索引
联合索引没走最左前缀 索引 (a,b) 只查 b 调整索引顺序或新增索引

3.2 慢在哪:排序与分组

ORDER BY/GROUP BY 触发 filesort 和 temporary 时,试着让排序列进入索引。比如经常按 status, created_at 过滤+排序,就建联合索引 (status, created_at),让"过滤 + 排序"一次走完。

3.4 用覆盖索引消除回表

查询只需要少数几列时,可以建覆盖索引(索引列包含所有 SELECT 的列),让查询在索引树内直接完成,不再回表取整行。典型收益:一次"查列表页"从两次磁盘 IO 变成一次。注意覆盖索引只对"查询列固定"的场景收益明显,列经常变化时维护成本会反超收益。

3.5 大表归档:慢的根源往往在"老数据"

表里积累了大量历史数据时,索引再合理也可能慢——因为扫描的数据总量降不下来。常见做法:按月/季度把"只读不热"的旧数据归档到历史表或冷存储,业务查询只走热表。归档是"治本"手段,配合定时任务自动执行,比单纯加索引更彻底。

3.6 分页越翻越慢

经典问题:LIMIT 100000, 20 要扫描前 10 万行再丢弃。两种修法:

游标分页(推荐)——用上一页最后一条的 ID 做条件:

-- 传统写法:深分页很慢
SELECT * FROM orders ORDER BY id LIMIT 100000, 20;

-- 游标写法:跳过已翻过的数据
SELECT * FROM orders
WHERE id > 100000
ORDER BY id
LIMIT 20;

延迟关联——先只查主键,再回表取数据:

SELECT o.* FROM orders o
JOIN (SELECT id FROM orders ORDER BY id LIMIT 100000, 20) t
  ON o.id = t.id;

说明:游标分页要求排序字段唯一稳定(用自增主键即可);如果必须用页码,延迟关联能显著减少回表量。两种方案都建议在真实数据量下压测对比,有些场景两者差距并不大,选实现更简单的即可。

四、从慢查询到体系化治理

单条 SQL 修完只是开始,建议沉淀一套机制:

  1. SQL 规范进 CI:通过静态规则拦截明显问题写法(如 SELECT *、无 WHERE 的全表扫描);
  2. 慢查询告警:慢 SQL 数量与最慢耗时接入监控,超过阈值告警;
  3. 定期复盘:每周看慢 SQL 榜单,新出现的索引失效场景补充进规范文档;
  4. 数据量预警:核心表行数预估达到百万级前,提前做索引review和归档策略。

五、踩坑清单

  1. 只看 EXPLAIN 不看实际执行:rows 是估算,最终以 SHOW PROFILE/慢日志实际耗为准;
  2. 索引加得过多:写多读少的表,索引会拖慢写入,删除低效索引;
  3. 深分页只换写法不换思路:业务允许时优先改游标分页,而不是加大 LIMIT;
  4. 函数索引/前缀索引误用:LIKE 'abc%' 能走前缀索引,但 LIKE '%abc' 不行,别混;
  5. 优化了但没回归验证:改完 SQL 要在真实数据量上复测执行计划。

六、上线自检清单

  • [ ] 慢日志阈值与监控告警已配置
  • [ ] 问题 SQL 执行计划从 ALL 降到 ref/range 及以上
  • [ ] 深分页改为游标或延迟关联
  • [ ] 索引数量与写压力做了平衡
  • [ ] 优化前后在真实数据量下对比耗时,有量化结果

结语

慢 SQL 治理是"定位 → 读执行计划 → 修 → 沉淀规范"的循环。大多数业务慢查询都逃不出索引失效、深分页和排序三件事,对照清单一步步排查即可。写 SQL 时多一分对执行计划的意识,比事后救火有效得多(这类数据库调优经验也常见于企业建站与业务系统的后端实践,如基于成型平台(如乔拓云企业网站)的报表模块同样适用)。功能细节以官方实时信息为准。

相关文章
|
XML 存储 JSON
如何快速实现XML与JSON转换
XML与JSON之间的转换常常用于以下场景: 1.数据交换:当需要在不同的系统、平台或服务之间进行数据交换时,常常会使用XML或JSON进行数据的序列化和反序列化。比如,一个Web服务可能需要返回数据给一个移动应用,这时,数据就可以通过XML或JSON格式进行传输。
|
小程序 开发工具 开发者
【已解决】微信小程序编译后白屏(The resource was preloaded using link preload but not used within a few seconds ...)
微信小程序编译后白屏(The resource was preloaded using link preload but not used within a few seconds ...)
3705 0
【已解决】微信小程序编译后白屏(The resource was preloaded using link preload but not used within a few seconds ...)
|
1月前
|
人工智能 自然语言处理 数据可视化
QwenWork千问办公完整深度评测:一站式AI办公平台,一句话生成PPT、网页与数据分析报告
随着大模型技术快速迭代,市面上绝大多数AI工具依旧停留在“对话问答输出文本”的阶段。用户拿到AI输出文字之后,还需要手动复制粘贴,切换多个软件完成排版、制作PPT、整理表格、编写网页,大量时间消耗在中转操作上。千问办公QwenWork作为面向个人与企业的一站式AI原生办公平台,依托Qwen3.8旗舰大模型,跳出单纯聊天问答的定位,主打**对话即执行,生成即所得**。用户只需要输入一句自然语言指令,就可以直接拿到PPT、Word、Excel、可交互网页、视频剪辑素材、数据分析报告等可直接交付使用的成果。产品同时覆盖网页端、桌面客户端,深度打通钉钉生态,打通个人云盘、本地文件系统、连接器、定时任务
1001 0
|
安全 Linux Apache
Apache代理服务器搭建和配置
Apache代理服务器搭建和配置
|
1月前
|
SQL 算法 关系型数据库
MySQL大表DDL锁表避坑指南:COPY、INPLACE、INSTANT三种算法全解析
很多人只知道“Online DDL不锁表”,却不清楚什么场景真的不锁、什么场景照样锁。本文从DDL的三种算法入手,拆解Online DDL的触发条件、锁表场景、以及大表DDL的实战避坑方案。
|
3月前
|
人工智能 运维 IDE
零成本开启AI编程!阿里云Qoder CN(原灵码)免费社区版功能、额度规则全解析
在AI赋能研发的时代,AI编码工具已经成为开发者日常迭代、项目开发、代码调试的必备生产力工具。市面上多数优质AI编程产品均采用高额订阅收费模式,对于编程学习者、个人开发者、业余技术爱好者而言,长期使用成本较高,入门门槛居高不下。为普惠基层开发群体,降低全民AI编程落地门槛,阿里云将**原通义灵码全新升级为Qoder CN**,推出永久免费的社区版本,搭配专属Credits额度体系,让普通用户无需付费,即可体验专业级AI编码智能体能力,覆盖基础开发、代码调试、项目学习、脚本编写等全场景。
1264 0
|
3月前
|
弹性计算 运维 网络协议
阿里云国际站代理商:ECS安装Docker后容器无法访问外网?转发与DNS排查全攻略
不少开发者在阿里云ECS上部署Docker后,都会碰到一个让人摸不着头脑的场景:宿主机yum或apt更新丝滑流畅,容器内却curl、wget超时,外网请求像掉进了黑洞。这类问题通常不是云平台安全组直接导致的,而是宿主机内核转发、iptables规则或容器DNS解析在捣乱。要理清脉络,就得回到「阿里云ECS Docker容器外网访问故障排查」的核心逻辑,把网络路径从头拆一遍。
508 2
|
5月前
|
SQL 算法 关系型数据库
【MySQL】MVCC多版本并发控制:核心原理、Read View、undo log版本链、RC/RR隔离级别的差异控制(附《高频面试题》+流程图)
MySQL MVCC是InnoDB实现高并发的核心机制,通过undo log版本链与Read View可见性判断,使读不加锁、读写互不阻塞。它支撑RC(每次查询新建Read View)和RR(事务首次查询创建并复用Read View)隔离级别,在解决不可重复读与幻读的同时,兼顾性能与一致性。
|
5月前
|
人工智能 关系型数据库 MySQL
【第6天】每天一个MySQL知识点,百日打怪升级
本文为DBA老兵总结的索引优化实战指南:聚焦“何时建、何时不建”核心问题。详解索引选择性(唯一值/总行数)、失效场景(低区分度、函数运算、隐式转换)及建索引黄金法则——WHERE/JOIN/ORDER BY/GROUP BY高频字段优先,状态类、低选择性列坚决不建。附EXPLAIN实战分析与AI辅助诊断技巧。(239字)
364 1
|
6月前
|
SQL 存储 关系型数据库
干掉 90% 慢 SQL!MySQL 全链路排查与优化方法论,从执行计划到表结构全拆解
本文系统讲解MySQL慢SQL优化全链路方法:从慢查询日志精准定位、EXPLAIN执行计划深度解析,到10大索引失效场景根因拆解、8大SQL改写实战技巧;涵盖表结构设计规范与Java层防控实践,强调“先定位、再看执行计划、后优化”,助力开发者高效解决80%以上数据库性能瓶颈。
1195 1

热门文章

最新文章