explain是mysql分析查询执行计划的核心工具,关键字段包括id(执行顺序)、select_type(查询类型)、type(连接类型,影响性能)、key/key_len(索引使用情况)、rows/filtered(扫描与过滤效率)、extra(额外操作),需联动判断索引使用、扫描行数及是否排序或建临时表。

EXPLAIN 是 MySQL 中用于分析查询执行计划的核心工具,它能帮你看清 SQL 语句实际是怎么被执行的,是调优慢查询的第一步。结果中每个字段都透露着优化线索,理解它们比盲目加索引更重要。
id:查询序列号,反映执行顺序
同一行的 id 值相同,表示属于同一个 SELECT;若 id 不同,则数字越大越先执行(MySQL 8.0+ 支持更复杂的执行顺序,但通常仍遵循“大 id 先执行”)。遇到 UNION 时,第二个及以后的 SELECT 会被标记为 UNION,其 id 为 NULL,而第一个 SELECT 的 id 为 1。
- id = 1:主查询(最外层 SELECT)
- id 相同:从上到下依次执行(关联查询常见)
- id 递增:子查询或派生表,数字越大越早执行
select_type:查询类型,揭示语句结构
它告诉你当前这行对应的是哪种 SELECT——是简单查询、子查询、联合查询,还是 MySQL 自动生成的临时表查询。
- SIMPLE:不包含子查询或 UNION 的普通 SELECT
- PRIMARY:最外层的 SELECT(含子查询时才出现)
- SUBQUERY:SELECT 中的子查询(不在 FROM 子句里)
- DERIVED:FROM 子句中的子查询(MySQL 会物化为临时表)
- UNION:UNION 后面的 SELECT
- UNION RESULT:UNION 结果集的去重合并操作
type:连接类型,直接影响性能
这是最关键的字段之一,表示 MySQL 如何查找表中行。从最优到最差大致为:system ≈ const > eq_ref > ref > range > index > ALL。应尽量避免 ALL(全表扫描)和 index(全索引扫描)。
- const:通过主键或唯一索引一次定位一条记录(如 WHERE id = 1)
- eq_ref:多表 JOIN 中,使用主键或唯一索引做等值关联(性能很好)
- ref:非唯一索引等值匹配(如 WHERE status = 'active',status 有普通索引)
- range:索引范围扫描(如 WHERE id BETWEEN 10 AND 20),合理利用索引
- index:遍历整个索引树(比 ALL 快,但仍可能慢,尤其索引宽时)
- ALL:全表扫描,无有效索引可用,必须优化
key 和 key_len:实际使用的索引及其长度
key 显示 MySQL 决定使用的索引名;key_len 表示该索引被用到的字节数(不是列长度,而是索引字段实际参与比较的长度)。它能帮你判断是否命中了联合索引的最左前缀。
- key 为 NULL:未使用索引(需检查 WHERE 条件、数据类型隐式转换、函数包裹等)
- key_len 较小:可能只用了联合索引的前几列(例如联合索引 (a,b,c),key_len 只够 a+b,说明 c 未生效)
- 注意字符集影响:utf8mb4 下 VARCHAR(10) 最大占 40 字节(10×4),而非 10
rows 和 filtered:预估扫描与过滤效率
rows 是 MySQL 预估需要扫描的行数(越小越好);filtered(5.7+ 引入)表示在存储引擎返回后,Server 层按 WHERE 条件进一步过滤的百分比(比如 filtered=10.00 表示只保留约 10% 的行)。
- rows 很大但 filtered 很小:说明索引选择性差,或者条件没走索引,靠 Server 层硬过滤
- rows 小但 filtered 更小:可能是隐式类型转换或函数导致索引失效,虽扫得少但过滤严
- 两者相乘 ≈ 实际参与计算的行数,是评估性能的关键参考
Extra:补充信息,藏着关键问题
这个字段内容杂但极重要,很多性能陷阱就藏在这里。
- Using where:WHERE 条件被用来过滤行(正常)
- Using index:覆盖索引,无需回表(好现象)
- Using index condition:ICP(索引条件下推),在引擎层提前过滤(5.6+,提升效率)
- Using filesort:需要额外排序(未走索引排序,应考虑添加有序索引)
- Using temporary:使用临时表(常见于 GROUP BY、DISTINCT、UNION、某些 JOIN)
- Using join buffer:使用连接缓冲区(说明关联字段没走索引,可能需加索引或调整 join_order)
看懂 EXPLAIN 不需要背下所有组合,关键是抓住 type、key、rows、Extra 这四个字段联动判断:有没有走索引?走了哪部分?扫了多少?还要不要排序或建临时表?把这几条理清,大部分慢查就有方向了。









