mysql执行计划生成后会立刻执行吗_mysql执行步骤说明

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

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

相关推荐