触发器本身无独立性能统计,其性能问题必须通过宿主DML语句定位:SQL Server应监控sys.dm_exec_requests中长时间运行的INSERT/UPDATE/DELETE请求,结合logical_reads、wait_type等指标分析;MySQL需启用performance_schema抓取触发器各阶段耗时;所有数据库均禁用在触发器中查询information_schema或performance_schema实时表,避免元数据锁阻塞。

触发器本身不慢,慢的是它被强制塞进事务主路径里同步执行——所有资源消耗都算在原始 INSERT/UPDATE/DELETE 头上,查触发器统计等于白查。
SQL Server:别查 sys.dm_exec_trigger_stats,去盯 sys.dm_exec_requests
SQL Server 的触发器没有独立 CPU、I/O 或逻辑读统计。sys.dm_exec_trigger_stats 只有 execution_count 和 last_execution_time,没法告诉你它拖慢了多少。真正该盯的是挂靠它的 DML 语句:
- 用
sys.dm_exec_requests筛出长时间运行的请求:WHERE command IN ('INSERT', 'UPDATE', 'DELETE') AND total_elapsed_time > 500000(0.5 秒阈值,OLTP 建议更严) - 通过
sql_handle拿到完整语句文本,确认是否操作了带触发器的表 - 如果
logical_reads高但cpu_time低,大概率是触发器里做了没索引的 JOIN 或全表扫描 - 搭配
sys.dm_exec_sessions查status = 'suspended'和wait_type,常见如LCK_M_U或IO_COMPLETION,说明锁或 I/O 被触发器逻辑卡住
MySQL:靠 performance_schema 挖耗时,别信 SHOW PROFILE
SHOW PROFILE 已弃用,且对触发器完全无效——它只显示外层语句耗时,根本看不到触发器内部哪一行卡住。必须用 performance_schema 实时抓取:
- 先启用关键 consumer:
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_statements_history', 'events_stages_history'); - 执行 DML 后,查触发器内各阶段耗时:
SELECT EVENT_NAME, TIMER_WAIT / 1000000000000.0 AS sec FROM performance_schema.events_stages_history WHERE NESTING_EVENT_ID IN (SELECT EVENT_ID FROM performance_schema.events_statements_history WHERE SQL_TEXT LIKE '%your_table%') ORDER BY TIMER_WAIT DESC LIMIT 5; -
TIMER_WAIT单位是皮秒,记得除以10^12换算成秒,别误当毫秒 - 重点看
stage/sql/Executing triggers和后续子阶段,比如stage/sql/Sending data如果异常长,说明触发器里 SELECT 扫描量过大
所有数据库共通陷阱:触发器里查系统表 = 主动加锁阻塞写入
在触发器里执行 SELECT COUNT(*) FROM information_schema.COLUMNS 或 SELECT * FROM performance_schema.events_waits_current,不是“有点慢”,而是直接在写入路径上埋雷:
-
information_schema表是动态视图,每次查询都要遍历内存结构、采集快照、校验权限;高并发下会锁元数据缓存,导致所有后续 INSERT/UPDATE 等待 -
performance_schema的实时等待事件表(如events_waits_current)在写入高峰期反向读取,极易触发 mutex 竞争 - 现象是单行插入从 2ms 涨到 800ms,
SHOW ENGINE INNODB STATUS显示waiting for table metadata lock - 绝对禁用的操作:
information_schema.PROCESSLIST、performance_schema.events_waits_current、sys.schema_table_statistics
监控真正有效的指标:看它挂靠的语句,而不是触发器本身
看到 sys.dm_exec_trigger_stats.execution_count 猛增,或 PerfMon 里 “Number of Triggers Fired” 上升,不等于系统变慢——轻量日志记录和拖垮系统的触发器,调用次数可能一样多。关键要看宿主语句是否同步恶化:
- SQL Server:
Lock Waits/sec突升 +Batch Requests/sec下跌 → 触发器事务太长或锁粒度太粗 - MySQL:
slow_query_log里同一条 INSERT 出现频次增加,且Rows_examined异常高 → 触发器里没走索引的 SELECT 在放大扫描量 - 通用信号:应用端超时错误增多,但数据库没报错;
sys.dm_exec_requests或pg_stat_activity显示大量会话卡在同一个表的 UPDATE/INSERT 上 - 最可靠验证法:临时
DISABLE TRIGGER(SQL Server/PostgreSQL)或重命名表隔离(MySQL),再跑原操作——延迟消失,就坐实问题
触发器的“慢”从来不是孤立现象,它是事务上下文、锁继承、同步执行三者叠加的结果。监控时盯着触发器本身,就像修车时只看仪表盘故障灯,却不去掀引擎盖——真正要拆开看的,是它被绑进去的那条 INSERT 或 UPDATE。

















