mysql如何判断SQL执行计划是否优化_mysql执行对比方法

来源:这里教程网 时间:2026-02-28 20:51:28 作者:

怎么看执行计划有没有优化

直接看

EXPLAIN
输出里有没有明显瓶颈项:如果
type
ALL
(全表扫描)、
key
NULL
(没走索引)、
rows
数量远超实际匹配行数,基本说明没优化好。重点盯
Extra
字段——出现
Using filesort
Using temporary
就得警惕,尤其是二者同时出现时,大概率是排序+分组逻辑触发了磁盘临时表。

对比两条SQL的执行效率该比什么

不能只看

EXPLAIN
的估算值,必须实测真实开销:

SELECT SQL_NO_CACHE ...
避免查询缓存干扰(MySQL 5.7 及以前);MySQL 8.0 要先确认
query_cache_type=OFF
开启慢日志并设低阈值:
SET long_query_time = 0.01;
,再跑 SQL,查
slow_log
表或日志文件里的
Query_time
Rows_examined
Rows_sent
SHOW PROFILE FOR QUERY N;
(需先
SET profiling = 1;
)看各阶段耗时,比如
Sorting result
Creating tmp table
占比过高,就对应到
EXTRA
里的问题

为什么
EXPLAIN FORMAT=TREE
更适合对比

MySQL 8.0+ 的树形执行计划能直观暴露嵌套层级和代价估算偏差:

FORMAT=TREE
会显示每个子节点的
cost
rows
,方便定位“哪个 JOIN 或子查询突然放大了数据量”
对比时重点关注
actual cost
(如果有启用
optimizer_trace
)和预估
cost
的差值,差 5 倍以上说明统计信息过期,要
ANALYZE TABLE
注意
-> Filter: ...
这类运行时过滤条件,它意味着 WHERE 下推失败,可能因函数包裹字段(如
WHERE YEAR(create_time)=2023
)导致索引失效

容易被忽略的对比陷阱

很多人只比单次执行时间,但缓存、连接状态、并发干扰会让结果失真:

第一次执行可能触发 buffer pool 加载,第二次才反映真实磁盘 I/O 压力;建议每条 SQL 至少跑 3 次,取中间值
RESET QUERY CACHE;
(旧版)或
FLUSH STATUS;
清空会话级状态,避免
Handler_read_*
计数污染
如果对比涉及
LIMIT
,注意
rows_examined
可能远大于
rows_sent
——优化器可能扫了 10 万行才凑够 10 条,这种“扫多送少”才是真实瓶颈

执行计划是否优化,最终得落在

Rows_examined
Query_time
的协同下降上,而不是某一行
EXPLAIN
字段看起来“变好了”。

相关推荐