Oracle、MySQL、SQL Server 的执行计划均不显示触发器节点,因其属于语句执行前/后的PL/SQL或T-SQL附加逻辑,不在CBO或查询优化器规划范围内;需通过禁用对比、单独EXPLAIN触发器内SQL、监控递归调用或事件时序等方式定位性能问题。

Oracle 中触发器不显示在 DBMS_XPLAN 的执行计划里
Oracle 的 EXPLAIN PLAN 和 display_cursor 输出中,**根本不会出现 Trigger 相关节点**。这不是你漏看了,是 Oracle 执行计划机制本身就不把触发器纳入计划树——它只展示 SQL 语句本身的访问路径、连接、过滤等逻辑,而触发器属于“语句执行后/前的附加动作”,被归入 PL/SQL 引擎调度,不在 CBO(Cost-Based Optimizer)规划范围内。
所以如果你在 display_cursor(... 'allstats last') 里没找到 Triggers 行,不是配置错,是设计如此。想确认触发器是否被调用,得换方式。
MySQL 触发器执行开销只能靠 SHOW PROFILES 或慢日志间接捕获
MySQL 同样不把触发器展开进执行计划。它的 EXPLAIN 只针对主 SQL,对 AFTER INSERT 或 BEFORE UPDATE 触发的逻辑完全静默。但触发器里的 SQL 仍会走优化器,只是你无法从父语句的 EXPLAIN 看到它们。
- 触发器内含
INSERT INTO log_table?这条语句自己可单独EXPLAIN - 触发器里调用了存储函数?该函数内部的查询无法被外层
EXPLAIN覆盖 - 用
SHOW PROFILES查看整条语句总耗时,再对比去掉触发器后的耗时差值,是定位开销的最直接办法 - 开启
slow_query_log并设long_query_time=0,能捕获触发器内所有慢子语句(需 MySQL ≥5.6 且 log_output='TABLE' 或 'FILE')
SQL Server 的图形执行计划里压根没有 Triggers 标签
SSMS 的“包括实际的执行计划”输出中,不会出现任何名为 Triggers、Trigger Execution 或类似字样的运算符节点。哪怕你在表上建了 10 个 AFTER UPDATE 触发器,执行计划图里也只显示 Clustered Index Update 或 Table Insert 这类主操作。
真正的问题藏在背后:
- 触发器代码若含
SELECT或JOIN,这些操作会以“隐藏子计划”形式执行,但不出现在图形界面中 - 用
SET STATISTICS XML ON获取 XML 执行计划,搜索<relop.></relop.>,可能发现额外的扫描节点——它们大概率来自触发器 - 更可靠的方式:在触发器开头加
RAISERROR('trig_start', 0, 1) WITH NOWAIT,配合 Profiler 抓取事件时序,确认是否卡在触发器内
排查触发器性能陷阱的关键动作清单
别指望执行计划自动标出触发器瓶颈。必须主动切片验证:
- 禁用触发器(
ALTER TABLE t DISABLE TRIGGER tr_name),重跑原 SQL,对比逻辑读、执行时间变化 - 把触发器内容复制出来,手动替换
NEW.column为具体值,单独EXPLAIN其中每条 DML - 检查触发器是否循环调用自身(比如
AFTER UPDATE里又UPDATE同一表),这类死循环不会报错,但会导致执行时间指数增长 - Oracle 中注意
AUTOTRACE ON统计里的recursive calls:数值突增往往意味着触发器引发大量递归 SQL(如审计日志插入触发索引维护)
最常被忽略的一点:触发器里没写 COMMIT 或 ROLLBACK 是对的,但它运行在主事务上下文中——一旦触发器某条语句全表扫描,整个事务的锁范围和持续时间就同步放大。这点永远比“执行计划有没有显示它”更致命。


















