我是小耶,干运营半路出家的野生DBA——写功课只是为了我踩过的坑,你们别再踩了!
上周讲了慢查询怎么抓。抓到慢SQL之后呢?很多同学执行完 EXPLAIN SELECT ... 看着输出结果一脸懵:type、rows、Extra 都是啥?
今天只说三列。看懂这三列,80%的慢SQL你就能自己分析。
1. type:访问类型(最核心)
- ALL:全表扫描。数据库把整张表从头读到尾。危险指数:爆表。看到这个,必须优化(加索引或改写SQL)。
- ref:使用非唯一索引查找。比如
WHERE name = '张三'且 name 列有普通索引。还行,但注意扫描行数。 - range:使用索引范围扫描。比如
WHERE id BETWEEN 1 AND 100或WHERE name LIKE '张%'。较优。 - const:使用主键或唯一索引等值查询,最多返回一行。完美。
记忆口诀:const > range > ref > ALL。越靠左越好。
2. rows:预估扫描行数
这个数字是优化器估算的需要检查的行数(不是最终返回的行数)。数字越大,查询越慢。如果显示 rows = 1000000,说明要扫一百万行,大概率有索引没生效。
注意:rows 是估算值,不同引擎统计可能不准,但趋势很有参考价值。
3. Extra:附加信息(常见坑)
- Using filesort:需要额外排序,无法利用索引排序。通常出现在
ORDER BY字段没索引。优化:给排序字段建索引。 - Using temporary:使用临时表。常见于
GROUP BY或DISTINCT没有索引。优化:给分组字段建索引。 - 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 filesort 或 Using temporary。三列搞定。
小耶在手,SQL不愁。
你今天 EXPLAIN 了没?晒出你的 type 列,我帮你把把脉。