mysql触发器是否会影响并发性能_mysql并发影响分析

来源:这里教程网 时间:2026-02-28 20:40:06 作者:

触发器会显著拖慢高并发写入场景

MySQL 触发器在

INSERT
UPDATE
DELETE
执行期间同步运行,属于事务的一部分。这意味着:只要触发器逻辑没跑完,该行(甚至整个表,取决于隔离级别和锁策略)就无法被其他事务安全修改。在每秒数百次以上写入的业务中(如订单创建、日志上报),一个耗时 5ms 的触发器就能让
innodb_row_lock_time_avg
明显升高,进而拉低整体
TPS

触发器里的 SELECT 或远程调用是并发杀手

以下操作在触发器中尤其危险:

BEFORE INSERT
里执行
SELECT ... FROM other_table WHERE x = NEW.y
—— 可能引发间隙锁或锁升级,阻塞其他插入
调用
SLEEP()
UUID()
(部分版本)、或自定义函数(含外部 HTTP 请求)—— 直接延长事务持有时间
对同一张表做
INSERT/UPDATE
(比如自增统计表)—— 极易触发
Deadlock found when trying to get lock
DELIMITER $$
CREATE TRIGGER order_after_insert_log
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
  -- ❌ 危险:跨表 UPDATE + 可能锁住 users 表的某一行
  UPDATE users SET last_order_time = NOW() WHERE id = NEW.user_id;
END$$
DELIMITER ;

替代方案比优化触发器更有效

多数“必须用触发器”的需求,其实有更低开销的选择:

把计数、状态更新等逻辑移到应用层,在主事务提交后异步处理(例如发 MQ 消息)
INSERT ... ON DUPLICATE KEY UPDATE
替代
BEFORE INSERT
中的查重逻辑
对审计类日志,改用
BINLOG
解析(如 Canal / Debezium),完全绕过事务链路
真需要强一致性且逻辑简单?优先考虑生成列(
GENERATED COLUMN
)或检查约束(
CHECK CONSTRAINT

监控触发器真实开销不能只看 slow log

slow_query_log
默认不记录触发器内部语句,容易误判。要定位瓶颈,必须开启:

performance_schema=ON
+ 启用
events_statements_history_long
performance_schema.events_statements_history_long
EVENT_NAME
包含
trigger
的记录
重点关注
LOCK_TIME
EXECUTION_ENGINE
(InnoDB vs MyISAM 行为差异大)

一个常被忽略的事实:即使触发器体为空,每次触发仍带来约 0.1–0.3ms 的固定上下文切换开销。在 QPS 超 2000 的写入集群里,这已足够让 p99 延迟跳变。

相关推荐