如何用 EXPLAIN 定位慢 SQL,type、rows、Extra 如何解读?

考查重点:执行计划与实际扫描。type 看访问方式、rows 看估算扫描量,Extra 查回表过滤、排序等;结合真实参数和执行统计验证瓶颈

本题目录

参考答案

核心回答

EXPLAIN 用于看优化器准备怎样执行 SQL。排查慢查询时,我会先找到具体 SQL 和参数,再结合计划判断:从哪张表开始、怎样访问、预计处理多少行、是否需要大量回表、排序或中间结果,而不是只确认“用了索引”。

以 MySQL 8.4 的传统表格格式为例,重点看:

  • type:表的访问方式,例如精确查找、范围访问、全索引扫描或全表扫描。
  • possible_keys、key、key_len:候选索引、实际选择的索引,以及所用键长度;结合索引列定义判断是否符合预期。
  • rows、filtered:预计检查的行数和表条件过滤后的保留比例,用于判断扫描量与后续连接的规模。
  • Extra:覆盖、索引下推、额外排序、临时表等信息,用来解释访问之后还在做哪些工作。

普通计划主要给出优化器估算。需要验证真实执行情况时,可使用 EXPLAIN ANALYZE 查看实际耗时、行数和循环次数;它会执行语句,使用时需要考虑数据规模与负载。

type 怎样解读?

常见类型可以这样理解:

  • const:通过常量条件匹配完整主键或唯一键等,最多定位一行。
  • eq_ref:连接时,对前面表的每个行组合,通过完整主键或唯一非空键,最多匹配当前表一行。
  • ref:按非唯一索引或键的部分前缀等值查找,一个查找值可能对应多行。
  • range:按一个或多个索引范围读取,范围也可能很大。
  • index:全索引扫描。若索引覆盖且较窄,可能比扫描整行划算,但仍可能检查大量索引项。
  • ALL:全表扫描。大表高频请求通常需要重点检查,小表或需要读取大部分行时也可能是合理选择。

这些类型能提示访问特征,不能当作整条 SQL 的固定性能排名。ref 若匹配大量行并反复回表,也可能比一次覆盖索引扫描更贵。

rows、filtered 和 key 怎样一起看?

InnoDB 的 rows 是估计值,不是本次真实扫描量。rows × filtered / 100 可帮助理解当前表过滤后向后续连接传递的预计行数,但还要结合连接顺序与算法。

例如在嵌套循环中,内侧一次只查少量记录,如果外侧产生很多行,内侧就可能被重复执行很多次。不能看到某一行 rows 小,就忽略整体循环次数。估计与实际相差很大时,还要检查数据倾斜、统计信息和谓词之间的相关性。

key 非空也不代表索引一定用于高效定位,它可能只是用于覆盖扫描;possible_keys 中没有列出的索引,也可能因为覆盖所需列而被扫描。key_len 需结合类型、字符集、可空性和具体范围分析,不能只数长度就断言所有条件都充分用于定位。

Extra 常见值说明什么?

  • Using index:所需列可由索引提供,具备覆盖访问的条件;仍要看扫描量。
  • Using index condition:使用索引条件下推,先检查索引项,再决定是否读取行;它不等于完全不用回表。
  • Using where:仍有条件判断,不能据此断定没有使用索引。
  • Using filesort:需要额外排序,名字不代表一定写磁盘。
  • Using temporary:需要临时表保存中间结果,不代表必然使用磁盘,也不自动等于瓶颈。

排序或临时表是否值得优化,要结合实际处理量和耗时;少量结果的排序可能很便宜。

怎样形成排查闭环?

先用慢查询记录、调用链或数据库监控确认主要成本,再根据计划提出假设,例如过滤太晚、连接放大、回表多或排序多。然后调整查询、索引或批量调用方式,在代表性数据和相近负载下比较结果正确性、执行耗时与处理量。

EXPLAIN ANALYZE 的多循环耗时按每次循环平均报告,父节点耗时也可能包含子节点,不能简单把整棵树的时间全部相加。计划仍解释不了所有端到端等待;数据库锁等待、连接池排队、网络和调用频次还需要其他观测配合。

例如批量日期查询把 SQL 写在循环里,即使每次都是较好的索引查找,重复往返的总成本仍可能很高。此时应一起评估批量查询与结果组装,而不是只把 type 调到更好看的名字。

对应教程

  • 电商问数:SQL生成与执行闭环:校验节点用 EXPLAIN 检查生成 SQL 能否解析;本文进一步解释返回计划怎样用于性能分析,解析成功本身不代表执行高效。

参考资料

相关面经

13 篇

启云方

AI 应用开发工程师
一面
查看原面经 →
如何排查索引失效?执行计划重点看哪些字段?

思锐卓远

后端开发实习生
实习一面
查看原面经 →
具体说说怎么用explain去优化数据。

中科星图维天信

后端开发
实习
查看原面经 →
如何分析一条 SQL 的执行计划?怎么看是否命中索引?

华盛通

Java实习生
实习
查看原面经 →
explain 能得到什么信息?

美团

AI 后端
校招秋招一面、二面
查看原面经 →
在实际项目中,如何判断一条 SQL 是否使用了索引?
追问
如何通过 EXPLAIN 判断 SQL 使用了哪个索引?
展开剩余 8 篇面经

华为

AI 开发工程师
校招秋招一面
查看原面经 →
会看慢sql吗?

百度

面经合集
查看原面经 →
Explain 中各个 Type 有什么区别?

去哪儿

测试开发工程师
一面
查看原面经 →
追问
怎么测试索引是否生效?

阿里巴巴(淘天)

AI 应用开发工程师
校招秋招一面
查看原面经 →
MySQL 查询做过哪些索引优化,explain 有没有用过

哔哩哔哩(B站)

Agent 开发
社招二面
查看原面经 →
SQL怎么看有没有走索引?

字节跳动

后端开发工程师(AI)
实习一面
查看原面经 →
线上慢SQL如何使用explain分析,type、rows、Extra字段分别代表什么,哪些指标说明SQL需要优化?

亚信科技

Java 开发工程师
实习
查看原面经 →
MySQL数据库相关:批量日期查询for循环内嵌SQL执行缓慢,如何优化?是否了解慢查询、explain执行计划,作用是什么?

京东

后端开发工程师(Agent)
实习一面
查看原面经 →
执行计划(explain)里你会看哪些列?

收录题集

1 个来源,共1 份题集

系统设计与后端基础

阿东玩 AI · AgentGuide · 1 条原题

查看题集 →

相关题目

4 题