mysql不存在触发器执行计划缓存,因其内部if等控制流不经过优化器,也不进入query cache(8.0+已移除),而是每次逐行解释执行,耗时源于字段读取、类型检查与布尔求值开销。

不是执行计划缓存失效,而是根本就没有执行计划缓存可言。 MySQL 的触发器内部逻辑(比如 IF、ELSEIF、ELSE)不参与查询优化器的计划生成流程,也不被缓存——它压根不在执行计划缓存体系里。
触发器里的 IF 不走优化器,也从不进 plan cache
MySQL 的执行计划缓存(query cache)早在 8.0.3 版本就已被彻底移除;而即使在旧版本中,它也只缓存 SELECT 语句的完整文本结果,完全不覆盖触发器内的控制流。更重要的是:触发器是过程式代码,在存储引擎层同步执行,由 SQL 解析器逐行解释,而非交给优化器生成执行树。所以不存在“缓存命中/失效”一说,只有“每次都要重新解析和求值”。
IF 嵌套多真正拖慢的是字段访问和类型检查开销
每层 IF 都会触发一次对 NEW.status、OLD.updated_at 等伪字段的重复读取和隐式类型转换判断。这不是 CPU 运算瓶颈,而是每次都要:
- 定位并拷贝
NEW行缓冲区中的字段值 - 做 NULL 检查 + 类型推导(比如把
TINYINT当布尔用) - 执行布尔表达式求值(
NEW.is_valid = 1 AND NEW.type IN ('A','B'))
批量插入 10 万行时,这段开销就被放大 10 万倍——但你看到的慢,不是因为“缓存没生效”,而是因为解析和判断本身太重。
为什么有人误以为是“缓存失效”?
常见混淆点来自两个地方:
- 把触发器外层 DML 的执行计划缓存(已不存在)和触发器内逻辑混为一谈
- 观察到“同样 SQL 有时快有时慢”,其实是触发器内条件分支实际执行路径不同(比如某次走了深层嵌套,某次提前
RETURN),导致耗时波动,被误判为“缓存抖动” - 用
EXPLAIN查 DML 语句时看不到触发器内部行为,只能看到主语句的扫描方式,进一步掩盖真实瓶颈
真正要盯住的,是 SHOW PROFILE 或 performance_schema 中的 trigger_execute 阶段耗时,而不是找一个根本不存在的“触发器执行计划缓存”。











