MySQL 优化器执行计划深度解读:EXPLAIN 的每个字段到底意味着什么?
type 决定访问方式,key 决定索引是否生效,rows 预估扫描量,Extra 揭示性能隐患。看懂 EXPLAIN,你就具备调优 SQL 的真正能力。
文章目录
MySQL 优化器执行计划深度解读:EXPLAIN 的每个字段到底意味着什么?
大家好,我是程序员卷卷狗。
在日常查询优化、慢 SQL 排查、数据库性能调优中,开发者最常接触的工具就是:
EXPLAIN 执行计划
然而许多人执行了 EXPLAIN,却完全看不懂:
- type=ALL 是什么?
- possible_keys 和 key 有何区别?
- rows=xxxxx 是不是越小越好?
- Extra 里面的 “Using where”、“Using index”、“Using filesort” 究竟意味着什么?
今天蒜皮就带你把 EXPLAIN 每个字段讲透,让你真正学会“看懂 SQL”的能力。
一、为什么必须学会使用 EXPLAIN?一句话理解
因为 MySQL 不会直接告诉你:
- 我为什么选了这个索引
- 我为什么要全表扫描
- 我是怎么优化你的 SQL 的
- 瓶颈在哪里
你必须通过 EXPLAIN 去“窥视”优化器的决策。
能看懂执行计划,才算真正具备 SQL 调优能力。
二、EXPLAIN 输出的核心字段总览(重要且必须掌握)
一个典型的 EXPLAIN 输出如下:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|
这些字段看似复杂,其实你只需要理解它们分别回答了什么问题。
蒜皮下面会按“从最关键 → 次关键”的顺序讲解。
三、type:最重要的字段,决定 SQL 是否走得快
type 表示访问方式,是优化器最重要的决策指标。
访问方式由快到慢如下:
- system(最优)
- const
- eq_ref
- ref
- range
- index
- ALL(最差,全表扫描)
一句话理解:
type 越靠前,扫描越少,性能越强;越靠后,扫描越多,性能越差。
常见情况解释:
① const:利用唯一索引精确查找
例如:
SELECT * FROM user WHERE id = 1;
id 是 PRIMARY KEY → 只扫描 1 行 → const
② ref:普通索引等值匹配
例如:
SELECT * FROM user WHERE name = '卷卷';
name 是普通索引 → ref
③ range:范围扫描
例如:
WHERE age > 20 AND age < 30
不能精确走唯一索引 → range
④ index:扫描整个索引树
虽然不读表,但会扫描索引的所有节点。
⑤ ALL:全表扫描(最差)
意味着:
没有用到任何有效索引。
绝大多数慢 SQL 都是 type=ALL。
四、possible_keys / key:优化器是怎么选索引的?
possible_keys:这个 SQL “可能”用到哪些索引
例如:
WHERE name='a' AND age=18
如果 name、age 都有索引:
possible_keys 会包含:
idx_name, idx_age
key:实际被选择的索引
最关键的是 key,而不是 possible_keys。
如果 key 显示 NULL,代表:
优化器没有选择任何索引 → 必定是低性能执行计划。
五、rows:SQL 大概扫描多少行,越少越好
rows 字段告诉你:
MySQL 预估要扫描多少行才能返回结果
例如:
rows=500000 → 预估扫描 50 万行(性能很差)
rows=10 → 扫描 10 行(性能很好)
rows≠结果行数,是扫描的行数,是性能瓶颈的重要指标。
六、Extra 字段:隐藏着性能真相的“黑匣子”
Extra 会包含很多重要提示,直接告诉你是否有性能问题。
1. Using where(普通过滤)
MySQL 通过条件过滤了一部分行。
不算坏,但说明不是所有过滤都通过索引完成。
2. Using index(覆盖索引,非常好)
意味着:
SQL 只使用索引就能完成查询,不需要回表。
这是 MySQL 查询的极限优化之一。
例如:
表结构:
id
name
age
索引:
KEY idx_name_age(name, age)
SQL:
SELECT name, age FROM user WHERE name='卷卷';
data 不需要回表 → Using index → 性能极高。
3. Using filesort(危险!)
意味着 ORDER BY 无法使用索引排序,需要在内存或磁盘中额外排序。
这是慢 SQL 的常见罪魁祸首。
4. Using temporary(更危险!)
意味着需要帮助表(临时表)来进行排序或分组。
例如 GROUP BY、DISTINCT 如果没有合适索引,会触发 Using temporary。
5. Using index condition(ICP 优化)
代表 MySQL 使用了 Index Condition Pushdown,属于好事,提高过滤效率。
七、通过一个例子彻底理解执行计划
假设 SQL:
SELECT id, name FROM user WHERE age > 18 ORDER BY name;
如果 EXPLAIN 显示:
- type = range
- key = idx_age
- rows = 10000
- Extra = Using where; Using filesort
说明:
- age 范围查询用了 idx_age(还不错)
- 但 ORDER BY name 没用索引 → 使用 filesort(很慢)
优化方式:
- 建联合索引 (age, name)
- 或者重写 SQL
通过一个执行计划就能定位问题,非常高效。
八、总结:理解 EXPLAIN,就是掌握 SQL 优化的入口
一句话总结整篇文章:
type 决定访问方式,key 决定索引是否生效,rows 预估扫描量,Extra 揭示性能隐患。
看懂 EXPLAIN,你就具备调优 SQL 的真正能力。
更多推荐



所有评论(0)