深浅主题
慢查询执行计划分析
问题现象
相同接口有时快有时慢,计划估算行数很少但实际耗时很高,JOIN 后中间结果剧增。
适用环境
MySQL 8.0.18+;EXPLAIN ANALYZE 会真正执行语句。
本文是可复用的排障示例,不代表某次个人生产事故。命令中的名称、账号和数据均为示例,执行前请替换为已确认的目标。
复现或诊断步骤
- 从慢日志或 performance_schema 找到 SQL 指纹,保留时间窗口、次数、耗时和扫描行数。
- 先用普通 EXPLAIN 分析连接顺序和访问路径。
- 在测试库或受控只读副本上,对有明确成本上限的 SELECT 使用 EXPLAIN ANALYZE,核对 actual rows、loops 和时间。
原因分析
估算基于统计信息与分布,可能低估关联扩张或条件相关性。单次执行慢也可能由锁、磁盘或资源竞争造成,不能完全归因于 SQL 文本;计划中的时间通常有包含关系,不应直接逐行相加。
修复示例
sql
EXPLAIN FORMAT=TREE
SELECT o.id, c.name
FROM orders o
JOIN customer c ON c.id = o.customer_id
WHERE o.created_at >= '2026-10-01'
ORDER BY o.created_at, o.id
LIMIT 50;
-- 仅在确认执行成本可接受的测试环境运行
EXPLAIN ANALYZE
SELECT id FROM orders WHERE customer_id = 1001 LIMIT 50;定位循环次数大且单次读取多的节点,减少关联前的数据范围,补齐有效索引并去除无用列。每次只改一个因素,保存原 SQL 与计划以便回退。生产诊断先限制时间和负载,不对未知成本语句直接 ANALYZE。
验证方法
使用同一参数集合比较执行计划、扫描行数和实际响应时间;在正常并发下复测。监测数据库 CPU、I/O 和锁等待,排除仅因缓存变热导致的假改进。
常见误区
EXPLAIN ANALYZE 不是无副作用的文本分析器。优化一个极端参数不代表所有租户和日期范围都改善,需覆盖常见与极端分布。