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

2次阅读

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

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

不会。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 中显示为 DERIVEDMATERIALIZED,但真实执行时物化开销远超预估

想看真实执行过程?用这些替代方案

如果需要观测实际执行行为,不能只靠 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_longevents_stages_history_long)追踪语句各阶段耗时
  • 对关键语句,直接加 SELECT ... INTO @var 或写入临时表,避免结果集网络传输干扰计时

真正卡住的往往不是计划生成,而是执行时的数据分布、缓存命中、锁竞争和资源争用——这些 EXPLAIN 一个都看不到。

text=ZqhQzanResources