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

1次阅读

执行计划是否优化需综合判断:看explain中type=all、key=NULL、rows过大,以及extra含using filesort/temporary;必须实测query_time和rows_examined,结合format=tree分析cost偏差与过滤下推失败,并多次运行取中间值。

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

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

直接看 EXPLAIN 输出里有没有明显瓶颈项:如果 typeALL(全表扫描)、keyNULL(没走索引)、rows 数量远超实际匹配行数,基本说明没优化好。重点盯 Extra 字段——出现 Using filesortUsing 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_timeRows_examinedRows_sent
  • SHOW PROFILE FOR QUERY N;(需先 SET profiling = 1;)看各阶段耗时,比如 Sorting resultCreating tmp table 占比过高,就对应到 EXTRA 里的问题

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

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

  • FORMAT=TREE 会显示每个子节点的 costrows,方便定位“哪个 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_examinedQuery_time 的协同下降上,而不是某一行 EXPLAIN 字段看起来“变好了”。

text=ZqhQzanResources