不会。EXPLAIN 生成执行计划只是分析 SQL,完全不触发实际查询执行。
EXPLAIN 不会访问表数据,也不加锁
MySQL 在遇到
EXPLAIN(或
EXPLAIN FORMAT=TRADITIONAL/JSON)时,仅做语法解析、语义检查、逻辑优化和物理计划生成,跳过「执行器」阶段。这意味着: 不会读取任何表的行数据,
SELECT类语句不会返回结果集 不会触发
WHERE条件中的函数调用(如
NOW()、
UUID()),也不会执行子查询 不会持有 MDL 锁(metadata lock),对线上 DML 几乎无影响 如果 SQL 本身有语法错误(如字段不存在),
EXPLAIN仍会报错——说明它走到了解析/校验环节,但止步于执行前
真实执行步骤:从 parse 到 execute 的完整链路
一条普通
SELECT的实际生命周期如下(简化版): Parse:词法 + 语法分析,生成解析树(
parse_tree) Resolve:绑定表名、列名,检查权限与对象存在性 Optimize:生成多个候选执行计划,基于统计信息(
INFORMATION_SCHEMA.STATISTICS、采样等)选择 cost 最小者;此阶段输出即为
EXPLAIN所展示内容 Execute:调用存储引擎接口(如
ha_innobase::index_read),真正读页、加锁、过滤、排序、返回结果
注意:
EXPLAIN停在 optimize 阶段末尾,execute 阶段完全跳过。
为什么有时候 EXPLAIN 看着快,实际执行却慢?
这是最常见的误判点,核心原因在于「计划静态,数据动态」:
统计信息过期(ANALYZE TABLE未及时运行),导致优化器低估/高估行数,选错索引或 JOIN 顺序
EXPLAIN不体现 runtime 开销:比如大结果集的网络传输、客户端 fetch 耗时、临时表磁盘 IO、
GROUP BY的 sort_buffer 溢出 参数化查询中,
EXPLAIN默认用常量推导(如
WHERE id = 1),但实际执行时若传入的是
NULL或高选择性值,行为可能不同(尤其涉及
IS NULL或隐式类型转换) 某些操作(如
UNION、子查询、窗口函数)在
EXPLAIN中显示为
DERIVED或
MATERIALIZED,但真实执行时物化开销远超预估
想看真实执行过程?用这些替代方案
如果需要观测实际执行行为,不能只靠
EXPLAIN: 加
SQL_NO_CACHE(5.7 及以前)或关闭
query_cache_type,再配合
SHOW PROFILES/
SHOW PROFILE FOR QUERY N查耗时分段 开启
slow_query_log并设
long_query_time = 0,捕获完整执行栈与时间戳 使用
performance_schema表(如
events_statements_history_long、
events_stages_history_long)追踪语句各阶段耗时 对关键语句,直接加
SELECT ... INTO @var或写入临时表,避免结果集网络传输干扰计时
真正卡住的往往不是计划生成,而是执行时的数据分布、缓存命中、锁竞争和资源争用——这些
EXPLAIN一个都看不到。
