怎么读 EXPLAIN?type、key、rows、Extra 分别说明什么?
结论先行:EXPLAIN 输出 MySQL 的执行计划,核心看四列:type 表示访问类型(越靠左越好)、key 表示实际命中的索引、rows 是预估扫描行数、Extra 提示是否回表/临时表/文件排序。定位慢 SQL 先看 type 是否 ALL、rows 是否过大、Extra 有没有 filesort 与 temporary。
一、常用字段速查
| 字段 | 含义 | 重点关注 |
|---|
| id / select_type | 子查询顺序与类型 | id 越大越先执行 |
| table | 访问的表(含别名) | 关联顺序 |
| type | 访问类型 | system > const > eq_ref > ref > range > index > ALL |
| possible_keys | 可能用到的索引 | 有 key 才说明真用了 |
| key / key_len | 实际使用的索引与长度 | key 为 NULL 即没走索引 |
| rows | 预估扫描行数 | 数量级越大风险越高 |
| Extra | 附加信息 | 见下方表格 |
二、type 从好到差怎么记
system → const → eq_ref → ref → range → index → ALL
主键/唯一命中 连接主键 普通等值 范围查询 全索引扫 全表扫
- const:主键或唯一索引等值命中,最多一行。
- ref:普通二级索引等值命中,可能多行。
- range:>、<、BETWEEN、IN 等范围定位。
- index:遍历整棵索引树,比 ALL 快但仍要避免(覆盖索引除外)。
- ALL:全表扫描,量大时是慢 SQL 的头号来源。
三、Extra 常见值与含义
| Extra | 含义 | 是否要警惕 |
|---|
| Using index | 覆盖索引,无需回表 | 好 |
| Using where | 存储引擎返回后再过滤 | 正常 |
| Using index condition | 索引下推 | 好 |
| Using temporary | 使用了临时表(常见于 group by/distinct) | 警惕 |
| Using filesort | 结果需要额外排序 | 警惕 |
| Using join buffer | join 未走索引 | 警惕 |
四、一条完整分析示例
EXPLAIN SELECT id, name FROM user WHERE name LIKE 'zh%' ORDER BY age;
-- type=range key=idx_name rows≈500
-- Extra=Using where; Using filesort
-- 结论:范围 OK,但排序没吃到索引,考虑建 (name, age) 联合索引消除 filesort
常见追问与记忆点
- 追问:rows 是精确值吗?不是,是优化器基于统计信息的估算,与 ANALYZE TABLE 时机有关。
- 追问:EXPLAIN 与 EXPLAIN ANALYZE(8.0)的区别?后者真正执行并给出实际耗时与行数。
- 记忆点:读计划四步——看 type 是否全表、看 key 是否为空、看 rows 量级、看 Extra 有无排序与临时表。