EXPLAIN看不懂?3个字段就能破案

10 阅读2分钟

我是小耶,干运营半路出家的野生DBA——写功课只是为了我踩过的坑,你们别再踩了!

上周讲了慢查询怎么抓。抓到慢SQL之后呢?很多同学执行完 EXPLAIN SELECT ... 看着输出结果一脸懵:type、rows、Extra 都是啥?

今天只说三列。看懂这三列,80%的慢SQL你就能自己分析。

1. type:访问类型(最核心)
  • ALL​:全表扫描。数据库把整张表从头读到尾。​危险指数:爆表​。看到这个,必须优化(加索引或改写SQL)。
  • ref​:使用非唯一索引查找。比如 WHERE name = '张三' 且 name 列有普通索引。​还行,但注意扫描行数​。
  • range​:使用索引范围扫描。比如 WHERE id BETWEEN 1 AND 100WHERE name LIKE '张%'。​较优​。
  • const​:使用主键或唯一索引等值查询,最多返回一行。​完美​。

记忆口诀:​const > range > ref > ALL​。越靠左越好。

2. rows:预估扫描行数

这个数字是优化器估算的需要检查的行数(不是最终返回的行数)。数字越大,查询越慢。如果显示 rows = 1000000,说明要扫一百万行,大概率有索引没生效。

注意:rows 是估算值,不同引擎统计可能不准,但趋势很有参考价值。

3. Extra:附加信息(常见坑)
  • Using filesort​:需要额外排序,无法利用索引排序。通常出现在 ORDER BY 字段没索引。优化:给排序字段建索引。
  • Using temporary​:使用临时表。常见于 GROUP BYDISTINCT 没有索引。优化:给分组字段建索引。
  • Using index​:覆盖索引,数据直接从索引获取,不回表。​这是好事​。
  • Using where​:通过索引过滤后还有额外条件需要回表检查。一般正常。
  • Using index condition​:MySQL 5.6+ 的索引下推优化,​不错​。
实战案例

某条慢查询:

EXPLAIN SELECT * FROM orders WHERE DATE(order_date) = '2026-05-01';

结果:type=ALL, rows=5000000, Extra=Using where

问题:对索引列用了函数 DATE(),导致索引失效,全表扫描500万行。

改写:

EXPLAIN SELECT * FROM orders WHERE order_date >= '2026-05-01' AND order_date < '2026-05-02';

结果:type=range, rows=523, Extra=Using index condition

速度快了几千倍。

小技巧
  • FORMAT=JSON 可看更详细成本:EXPLAIN FORMAT=JSON SELECT ...
  • 生产环境谨慎使用 EXPLAIN,它不会真的执行查询,安全。

小结​:遇到慢SQL,先看 type 是不是 ALL;再看 rows 是不是很大;最后看 Extra 有没有 Using filesortUsing temporary。三列搞定。

小耶在手,SQL不愁。

你今天 EXPLAIN 了没?评论区晒出你的 type 列,我帮你把把脉。