MySQL 8.0执行计划分析利器:EXPLAIN ANALYZE到底比EXPLAIN强在哪?

大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!

前两天一个同事跑过来问我:"小耶,你看这个执行计划,type是ref,rows是1000,Extra里用了索引,为啥还是慢?"

我看了眼SQL,又看了眼他的执行计划,问了一句:"你用的是EXPLAIN还是EXPLAIN ANALYZE?"

他说:"EXPLAIN啊,用了十几年了。"

------问题就出在这儿。

EXPLAIN给你看的是"优化器的预测",不是"实际执行的结果" 。优化器说rows=1000,实际可能扫了100万行;优化器说用索引,实际可能回表回了10万次。

MySQL 8.0.18开始引入的EXPLAIN ANALYZE,直接把实际执行时间和实际行数输出给你看,把执行计划分析这件事从"猜"变成了"看"。

一、传统EXPLAIN的局限

传统的EXPLAIN输出,你看到的是:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE orders ref idx_user_id idx_user_id 4 const 1000 Using index condition

rows=1000 ------ 这是优化器估算的需要扫描的行数,不是实际扫描的行数。

如果统计信息过期、数据分布倾斜、或者优化器的基数估算出了偏差,这个数字可能和实际情况差一个数量级。

你基于一个错误的估算去优化,方向可能从一开始就偏了。

二、EXPLAIN ANALYZE带来了什么

EXPLAIN ANALYZE实际上会执行SQL (是的,它会真的跑一遍),然后输出每个执行步骤的实际执行统计信息:

bash 复制代码
EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 12345 AND create_time > '2026-01-01';

输出示例(MySQL 8.0+):

bash 复制代码
-> Filter: (orders.create_time > '2026-01-01')  (cost=1234 rows=1000) (actual time=0.5..45.2 rows=856 loops=1)
    -> Index lookup on orders using idx_user_id (user_id=12345)  (cost=1234 rows=1000) (actual time=0.4..42.1 rows=12345 loops=1)

关键差异:

传统EXPLAIN EXPLAIN ANALYZE
估算行数(rows) 实际行数(actual rows)
估算成本(cost) 实际执行时间(actual time)
只看计划 看到每个步骤的真实开销

在上面这个例子里,优化器估算rows=1000,实际扫描了rows=12345------差了12倍。如果你只看传统EXPLAIN,可能觉得"只扫1000行,没问题",但实际上回表回了1万多行,慢是必然的。

三、怎么用EXPLAIN ANALYZE定位问题

第一步:找到最慢的那个步骤

actual time告诉你每个步骤实际花了多少毫秒。哪一步时间最长,哪一步就是瓶颈。

第二步:对比估算值和实际值

如果rows和actual rows差距很大(比如差10倍以上),说明统计信息可能过期了------先更新统计信息,再看看执行计划有没有变化。

第三步:看loops

loops表示这个步骤被执行了多少次。如果loops很大(比如>1000),说明有大量的重复执行------可能是嵌套循环连接(Nested Loop Join)的驱动表选错了,或者子查询被反复执行。

四、注意事项

  • EXPLAIN ANALYZE会实际执行SQL ,所以不要在写操作上直接跑------先在测试环境或只读从库上验证

  • 对于耗时很长的SQL,EXPLAIN ANALYZE本身也要跑那么久,要有耐心

  • MySQL 5.7及以下版本不支持,需要升级到8.0.18+

  • EXPLAIN ANALYZE的输出比传统EXPLAIN详细得多,需要花时间熟悉格式

五、小结

EXPLAIN用了十几年,是时候升级到EXPLAIN ANALYZE了。前者给你看"优化器的预测",后者给你看"实际执行的结果"。从"猜"到"看",这是执行计划分析这件事上最大的认知升级。

小耶在手,SQL 不愁

还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽......我们下次见~

相关推荐
草莓熊Lotso2 小时前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
Lethehong7 小时前
Oracle 加个字段,目标库就报错?KFS 用“先拆后组“打通异构 DDL
数据库·oracle
Web极客码8 小时前
锁定真正的磁盘卡顿:我用 OpenCode 配合 eBPF 诊断 NVMe 队列深度延迟与 I/O 写放大
数据库·oracle
cspttty8 小时前
2027用户研究求职准备:应用统计学如何补齐研究设计与业务表达
大数据·数据库
roman_日积跬步-终至千里9 小时前
【数据Agent论文·查询与语义|05】Spider:为什么换一个数据库,模型就不会查了?
数据库·数据分析
猫咪很可爱10 小时前
Oracle RAC 启动失败排查:私网通信与内核参数优化实战
运维·数据库·oracle
XLYcmy10 小时前
《数字经济赋能城市低碳治理的路径研究检索报告》审阅与修改指导意见——基于完整检索报告体例的完整性诊断、学术规范核查与方法论纠偏 上
数据库·ai·chatgpt·文心一言·检索·知网·豆包
泡海椒10 小时前
JQuick-SQL 快速开始:注册内存表并执行查询
数据库·windows·sql
ss27311 小时前
PG实战笔记 | 09 PostgreSQL psql客户端基本操作
数据库·笔记·postgresql
电商API_1800790524711 小时前
反向海淘多币种结算:汇率该在哪个时点被冻结
java·开发语言·数据库·跨境电商·1688 api