show profile 无法监控触发器执行时间,因其隐式执行且不单独计入 profiles;必须启用 performance_schema 的 stage/sql/trigger instrument 并查询 events_stages_history_long 才能获取纳秒级耗时,但生产环境需警惕历史表容量限制和 mysql 8.0.22+ 中部分场景计时不准确问题。

触发器执行时间不能用 SHOW PROFILE 监控
触发器是隐式执行的,不作为独立语句出现在会话的 SHOW PROFILES 列表里。你执行一条 INSERT,哪怕它触发了 3 个 BEFORE 和 2 个 AFTER 触发器,SHOW PROFILES 只记录那条 INSERT 的总耗时,不会拆解触发器内部开销。MySQL 从不把触发器逻辑当作“可 profile 的 query”,所以别白费力气设 SET profiling = 1 然后查 SHOW PROFILE FOR QUERY N —— 它压根不会出现。
必须用 performance_schema 捕获触发器阶段耗时
触发器执行属于 SQL 执行流程中的 stage/sql/trigger 阶段(MySQL 5.7+),但默认关闭采集。要看到它,得手动打开对应 instrument:
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME = 'stage/sql/trigger';UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_stages_history_long';
之后再跑触发器相关语句(比如 INSERT INTO orders ...),就能查到触发器阶段的纳秒级耗时:
SELECT EVENT_NAME, TIMER_WAIT/1000000000 AS sec FROM performance_schema.events_stages_history_long WHERE EVENT_NAME LIKE 'stage/sql/trigger%' ORDER BY TIMER_START DESC LIMIT 5;
注意:TIMER_WAIT 是纳秒单位,除以 1000000000 得秒;若为 NULL,说明该阶段未被计时或已被清理。
按触发器名称聚合平均耗时需关联 events_statements_history_long
单看 stage 表只能知道“有触发器执行”,但不知道是哪个触发器。要按触发器名统计平均耗时,得把 events_stages_history_long 和 events_statements_history_long 关联起来:
- 先确认触发器名在语句文本中是否可见:执行
SELECT SQL_TEXT FROM performance_schema.events_statements_history_long WHERE SQL_TEXT LIKE '%INSERT%orders%' ORDER BY TIMER_START DESC LIMIT 1;,看是否含TRIGGER或触发器名 - 若不可见(多数情况),只能靠
EVENT_NAME中的路径推断,例如stage/sql/trigger/after_insert/orders_before_update(实际路径取决于定义) - 聚合平均值示例(仅适用于路径含触发器名的场景):
SELECT SUBSTRING_INDEX(EVENT_NAME, '/', -1) AS trigger_name, ROUND(AVG(TIMER_WAIT)/1000000000, 6) AS avg_sec FROM performance_schema.events_stages_history_long WHERE EVENT_NAME LIKE 'stage/sql/trigger/%' GROUP BY trigger_name;
生产环境长期监控要避开两个坑
performance_schema 的历史表(如 events_stages_history_long)有固定大小,默认只保留最近约 10000 条事件。高频触发器会快速刷掉旧记录,导致无法回溯。更严重的是:stage/sql/trigger instrument 在 MySQL 8.0.22+ 中对某些触发器类型(如基于行复制的从库触发器)可能完全不生效 —— 官方文档明确标注“timing may be inaccurate or missing”。
真正稳得住的做法是:在应用层埋点,记录触发器所依赖的主语句执行前后时间戳;或改用审计插件(如 MariaDB Audit Plugin 或 Percona Audit Log)捕获完整语句上下文。原生方案只适合短期定位,别指望它扛住 24/7 的生产流量。











