Extra 关键值是什么
EXPLAIN 的 Extra 列藏着执行方式的关键信号:Using index 表示覆盖索引、无需回表;Using index condition 表示进行了索引条件下推;Using where 说明还要回表后过滤;Using filesort 表示需要额外排序;Using temporary 表示用到了中间临时表;Using join buffer 表示被驱动表缺少可用索引。看到 filesort 或 temporary 就该评估改写方式或补索引。
基本信息
| 适用版本 | MySQL 5.7 / 8.0;EXPLAIN ANALYZE 需 8.0.18+ |
|---|---|
| 关键取值 | Using index / index condition / where / filesort / temporary |
| 连接相关 | Using join buffer 与哈希连接提示被驱动表无索引 |
| 深入分析 | EXPLAIN FORMAT=JSON 或 EXPLAIN ANALYZE 看实际耗时 |
| 判定原则 | Extra 只说明方式,是否要优化还要结合数据量 |
典型使用场景
- 优化排序:出现 filesort 时补上顺序匹配的联合索引
- 优化分组:出现 temporary 时检查 GROUP BY 与 DISTINCT 写法
- 确认覆盖索引:看到 Using index 说明无需回表
- 检查连接方式:join buffer 出现时给被驱动表补索引
- 排查全表扫描:结合 type 与 rows 判断是否走了全表
- 验证优化效果:改索引前后对比 Extra 与 rows 变化
- 回归验证:索引调整后再用 EXPLAIN ANALYZE 核对实际执行耗时
定位排序与分组问题
定位排序与分组问题
EXPLAIN SELECT * FROM appdb.orders WHERE user_id = 1 ORDER BY created_at DESC LIMIT 20;
-- Extra: Using filesort => 考虑 (user_id, created_at) 联合索引
EXPLAIN SELECT status, COUNT(*) FROM appdb.orders GROUP BY status;
-- Extra: Using temporary; Using filesort => 考虑在 status 上建索引
EXPLAIN SELECT id FROM appdb.orders WHERE user_id = 1;
-- Extra: Using index => 覆盖索引,无需回表
EXPLAIN ANALYZE SELECT * FROM appdb.orders WHERE user_id = 1 ORDER BY created_at DESC LIMIT 20;
-- 8.0.18+ 能看到实际耗时与循环次数,比估算更可靠Extra 速查
| 取值 | 含义 | 优化方向 |
|---|---|---|
| Using index | 覆盖索引,无需回表 | 良好状态 |
| Using index condition | 索引条件下推 | 良好状态 |
| Using where | 回表后再过滤 | 看过滤比例,必要时补索引 |
| Using filesort | 需要额外排序 | 补与排序匹配的联合索引 |
| Using temporary | 使用中间临时表 | 审视分组去重写法与索引 |
| Using join buffer | 被驱动表无可用索引 | 补索引或调整连接顺序 |
filesort 不一定落磁盘:小结果集在内存里排序也很快,先看数据规模再决定是否优化。
出现 temporary 时要确认是否由 GROUP BY 或 DISTINCT 引起:把过滤列与分组列按顺序放进同一个联合索引,通常能让中间临时表消失。
EXPLAIN 里的 rows 是估算值,统计信息过期时偏差可能很大;先用 ANALYZE TABLE 更新统计信息再判断,得出的优化结论才可靠。