看 EXPLAIN 不能像背字段说明书。id、type、key、rows、Extra 都重要,但它们最终服务于一个问题:MySQL 准备怎样访问数据。
执行计划不是实际执行日志,而是优化器给出的访问方案。读它的顺序应该是:从哪张表开始,怎么访问,用哪个索引,预计扫多少行,是否还要排序、临时表或回表。
先把机制边界说清楚
EXPLAIN 是 MySQL 对“准备怎么执行这条 SQL”的解释。它不是实际执行日志,而是执行前的计划。核心不是背字段,而是还原访问路径:从哪张表开始,怎么访问,用哪个索引,预计扫多少行,是否还要排序、临时表或回表。
整体路径
上面这张图先看粗线条:宏观上,执行计划把 SQL 从声明式语句翻译成过程式路径。Server 层先解析和改写 SQL,优化器生成候选计划并估算成本,选出计划后执行器调用存储引擎。EXPLAIN 展示的是这条路径的骨架。
底层流程
底层拆解先看数据结构。「执行计划」至少涉及下面几类结构:
- 访问类型 type:完整等级序列是
system > const > eq_ref > ref > range > index > ALL。const是主键或唯一索引等值匹配(最多 1 行);eq_ref是 join 时被驱动表用主键/唯一索引等值匹配(最多 1 行);ref是非唯一索引等值匹配或唯一索引的最左前缀(可能多行);range是索引范围扫描;index是扫描整棵索引树;ALL是全表扫描。从左到右性能递减,看到ALL或index就要警惕。 - key 与 possible_keys:候选索引和最终索引选择。
- key_len:索引实际使用的字节数,能反推联合索引用了几个字段。计算口径:int=4 字节、bigint=8 字节、char(n) 在 utf8mb4 下按
4n计、date=3、datetime=8、timestamp=4;如果字段允许 NULL 加 1 字节;变长类型(varchar)加 2 字节记录长度。比如联合索引(a int, b varchar(10), c int)上WHERE a=1 AND b='x',key_len = 4 + (4×10+2) = 46,说明 a、b 都用上了,c 没用。 - rows 与 filtered:优化器对扫描量和过滤率的估算。
- Extra:
Using index(覆盖索引,不回表)、Using where(Server 层过滤)、Using index condition(索引下推 ICP)、Using filesort(额外排序)、Using temporary(用临时表)各有不同成本含义。
再看完整执行流程:
- 对 SQL 做语法解析和语义检查。
- 生成候选访问路径。
- 根据统计信息估算每条路径成本。
- 选择计划并输出 EXPLAIN 字段。
- 实际执行时可能受运行时数据和缓存状态影响。
取舍与边界
版本差异上,MySQL 8.0 的 EXPLAIN 支持 FORMAT=JSON、EXPLAIN ANALYZE 等更强能力,后者能看到实际执行耗时和行数。5.7 时代更多依赖传统 EXPLAIN 和慢查询日志结合判断。
EXPLAIN 的短板是它展示的是计划,不等于真实执行全过程。rows 是估算,不是实际值;Extra 是信号,不是结论;小表全表扫可能没问题,大表 range 也可能很慢。
典型问题:用机制化例子排查
执行计划适合用来还原访问路径:从哪张表开始,走哪个索引,预计多少行,是否回表、排序或临时表。字段要看,但不要停在字段解释。
可以落到这些动作:
- 阅读顺序固定为 table/type/key/rows/Extra,不要平均用力。
- 看到 Using filesort 和 Using temporary,要结合数据量判断是否需要索引顺序。
- MySQL 8.0 优先用 EXPLAIN ANALYZE 校准估算和实际。
- 把执行计划变化纳入发布检查,避免加索引或改 SQL 后计划漂移。
收束:EXPLAIN 是访问路径说明
EXPLAIN 的价值不在背字段,而在还原访问路径。能从计划里看出扫描、回表、排序和临时表,慢查询排查才算真正进入数据库内部。
关于十三Tech
我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。
我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。
如果你想继续跟完这套「图解 MySQL」,欢迎关注公众号 「十三Tech」。后续会继续按机制、图解和实战排查这条线更新。

