不会。explain仅分析sql并生成执行计划,不访问表数据、不加锁、不执行函数或子查询,停留在优化阶段末尾,跳过执行阶段。

不会。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 一个都看不到。










