触发器会显著拖慢INSERT/UPDATE/DELETE,同步执行导致0.1–5ms单行延迟,高并发下p95延迟翻3倍以上;禁止在触发器中修改原表、避免无索引查询和LIKE全模糊匹配;binlog_format必须为ROW以防主从不一致。

触发器会让 INSERT/UPDATE/DELETE 变慢多少
会,而且是同步、实时、不可绕过的变慢。MySQL 必须等触发器逻辑全部执行完,主语句才算成功——哪怕触发器只做 INSERT INTO log_table VALUES (NEW.id, NOW()),这条日志写入的耗时就直接加到你的业务 SQL 响应时间里。
实测中,一个含简单跨表 INSERT 的触发器,单条 INSERT 平均延迟增加 0.2–5ms;在 1000+ QPS 场景下,p95 延迟可能翻 3 倍以上,根本原因是锁竞争和事务日志压力被同步放大。
- 空触发器也有约 0.1–0.3ms 固定上下文开销
-
INSERT INTO ... SELECT或LOAD DATA INFILE这类批量操作,触发器会被逐行调用,性能衰减呈线性甚至指数级 - 慢日志(
slow_query_log)默认不记录触发器内部语句,容易误判“主 SQL 很快”,实际瓶颈全在触发器里
为什么 AFTER UPDATE 里再 UPDATE 同一张表会报错
MySQL 明确禁止在触发器中修改当前正在被 DML 操作的表,这是硬限制,不是配置问题。比如 AFTER UPDATE ON orders 触发器里执行 UPDATE orders SET status = 'processed' WHERE id = NEW.id,MySQL 8.0+ 直接报错:ERROR 1442 (HY000): Can't update table 'orders' in stored function/trigger。
这不是为了“防递归”而做的柔性限制,而是事务引擎层面的隔离约束:同一事务中对同一张表的多次 DML 会引发元数据锁冲突或状态不可控。
- BEFORE 类型允许修改
NEW值(如自动填充updated_at),但仅限本行字段 - AFTER 类型只能用于日志、通知、异步标记等“只读旁路”动作,不能反向写入原表
- 若真需状态联动(如订单更新后刷新用户最后下单时间),必须拆到应用层或用异步消息,不能塞进触发器
触发器里查大表或 LIKE 匹配为什么 CPU 爆高
SELECT COUNT(*) FROM orders 或 NEW.name LIKE '%xxx%' 这类操作,在触发器里每行都执行一次,等于把 O(n) 操作放大了 N 倍(N 是 DML 影响行数)。索引完全失效,全表扫描或逐行字符串匹配直接拉满 CPU。
更危险的是,这类查询常带间隙锁(Gap Lock),在高并发插入时极易阻塞其他事务,表现为 SHOW PROCESSLIST 中大量线程卡在 Updating 或 Waiting for table metadata lock。
- 避免在触发器里做任何无强过滤条件的
SELECT,尤其不能查没索引的字段或大表 -
LIKE '%xxx'或LIKE '%xxx%'无法走索引,改用前缀匹配LIKE 'xxx%'或提前建函数索引(MySQL 8.0.13+) - 如果只是查配置类小表(如
config_cache),务必加WHERE id = NEW.config_id这种等值条件,且该字段要有索引
binlog_format 和主从延迟的隐性关联
触发器本身不写 binlog,但它执行的语句会生成额外 binlog 事件。当 binlog_format 不是 ROW 时,这些事件可能无法正确回放,导致主从数据不一致;即使设为 ROW,从库也必须串行回放每个触发器产生的语句,一旦触发器频繁更新统计表或日志表,Seconds_Behind_Master 就会持续上涨。
典型现象是:主库 SHOW PROCESSLIST 看着很空,但从库复制线程卡住,SHOW ENGINE INNODB STATUS 里反复出现 Waiting for table metadata lock —— 根源往往就是触发器在从库上重复执行跨表 UPDATE,锁住了目标表。
- 必须确认
binlog_format = ROW,MIXED或STATEMENT下触发器行为不可预测 - 触发器产生的所有写操作(尤其是
UPDATE统计表)都要评估是否真的需要实时强一致;多数场景可降级为定时任务补算 - 监控
performance_schema.events_statements_history_long中EVENT_NAME含trigger的记录,重点关注LOCK_TIME和执行引擎类型
SELECT 或一个没索引的 LIKE,都可能让整张表的写入吞吐断崖下跌。



















