EXPLAIN实战:5分钟定位慢查询

  • 约1126字
  • 技术
  • 2026年4月27日

上周线上一个查询突然超时,查了半天才定位到问题。

同事说某个接口超时了,响应时间从200毫秒变成了30秒。我第一反应是数据量变大导致的,但查了数据库记录,最近一周数据只涨了5%,不应该啊。

后来用EXPLAIN分析了一下,发现问题根本不是数据量,而是一个看似简单的SQL压根没用索引。

什么是EXPLAIN

EXPLAIN是MySQL提供的查询分析工具,直接在SELECT前面加个EXPLAIN就能看到执行计划。不需要任何额外权限,用法非常简单:

EXPLAIN SELECT * FROM orders WHERE user_id = 12345;

执行后会返回一串字段,其中最关键的是这几个:

  • type:访问类型,ALL全表扫描最慢
  • key:实际使用的索引
  • rows:预计扫描行数
  • Extra:额外信息,是否 Using filesort、Using temporary

5种常见问题的EXPLAIN特征

1. 全表扫描(type = ALL)

+----+-------------+-------+------+---------------+
| id | select_type| type  | key  | rows          |
+----+-------------+-------+------+---------------+
|  1 | SIMPLE     | ALL   | NULL| 5000000      |
+----+-------------+-------+------+---------------+

这种就是最糟糕的情况,500万行全扫描。赶紧检查WHERE条件字段有没有索引。

2. 索引失效(type = ref 但 key = NULL)

明明有索引为什么不走?常见原因:

  • 类型不匹配:字符串字段用数字WHERE
  • 函数处理:WHERE YEAR(created_at) = 2026
  • 隐式转换:字符串字段没加引号

3. 索引选择性低(rows 接近全表)

|  1 | SIMPLE     | index | idx_xxx| 4800000      |

虽然用了索引,但扫描行数接近全表。这种情况考虑加 selectivity 更高的条件,或者改用复合索引调整字段顺序。

4. Using filesort(Extra 包含这个)

| Extra                           |
| Using filesort; Using where     |

意味着MySQL需要在内存中额外排序,数据量大时会明显变慢。解决办法是让ORDER BY字段也走上索引。

5. Using temporary(Extra 包含这个)

| Extra                           |
| Using temporary; Using filesort|

创建了临时表,通常是GROUP BY或DISTINCT没走上索引。先确保分组字段有索引。

快速定位问题4步法

第一步:运行EXPLAIN,看type字段是不是ALL 第二步:检查key字段是不是NULL 第三步:看rows是不是远大于实际返回行数 第四步:检查Extra有没有filesort或temporary

按照这个顺序,5分钟内基本能定位90%的慢查询原因。

实际案例

回到开头那个30秒的查询,EXPLAIN结果是这样的:

EXPLAIN SELECT * FROM orders WHERE created_at > '2026-01-01';
+----+-------------+-------+------+---------------+
| id | select_type| type  | key  | rows          |
+----+-------------+-------+------+---------------+
|  1 | SIMPLE     | ALL   | NULL| 4800000      |
+----+-------------+-------+------+---------------+

问题很明显:created_at字段有索引,但查询用的是>范围查询,MySQL预估这个条件会筛掉大量数据,所以直接走全表扫描。

改成带明确上界的范围查询后,响应时间回到了200毫秒。

小结

SQL慢不一定是因为数据量大,很可能是查询写法或索引使用有问题。学会用EXPLAIN,5分钟就能定位大多数性能瓶颈。

下次遇到查询超时,别急着加服务器配置,先跑一下EXPLANGE看看执行计划。多数时候,问题在代码层面就能解决。

相关文章

Standard JS 代码规范和提交代码时检查

公司的 JavaScript 项目最开始有一个代码规范,也用 jsHint 写了检查脚本。但是随着团队人员的逐渐增加和项目的时间紧迫,有一段时间没有特别强调要去做代码规范的检查。

查看更多

使用 Markdown 写微信公众号文章

微信公众号的编辑器,缺乏基本的排版功能。作为程序员,习惯了使用 Markdown 来写文章。于是找到其中一个开源的 Markdown 写公众号编辑器,根据自己的排版需求做了部分修改。

查看更多

Git 常见命令总结

Git 是分布式版本控制系统,由 Linux 之父 Linus Torvalds 发起。和 svn 等版本控制的最大区别在于分布式,每个人在本地都有一份完整的代码历史库,在不联网的情况下就可以查所有历史并提交代码。

查看更多