因为复杂逻辑会直接卡住主事务、放大锁竞争、逃逸所有监控,且问题定位成本极高;触发器被硬塞进主DML事务生命周期,逐行同步执行,无法异步或批处理,导致锁不释放、慢查询隐匿、死锁频发、监控失效。

因为复杂逻辑会直接卡住主事务、放大锁竞争、逃逸所有监控,且问题定位成本极高。
触发器里写复杂逻辑 = 把事务时间交给不可控代码
触发器不是独立线程,它被硬塞进主 DML 事务生命周期里。INSERT 执行完,触发器里一个没索引的 SELECT COUNT(*) FROM audit_log WHERE user_id = NEW.user_id 还在扫表,整个事务就一直开着:锁不放、undo log 不 purge、binlog 一直攒着。
- 常见现象:
SHOW PROCESSLIST显示Updating或Waiting for table metadata lock,但真正卡住的是触发器内那条慢查询 - 批量导入 10 万行?触发器逐行执行 → 事务持续几十秒,
INFORMATION_SCHEMA.INNODB_TRX中TRX_ROWS_MODIFIED瞬间飙高 - 哪怕只是加个空触发器,也有 0.1–0.3ms 固定开销;含
SELECT ... FOR UPDATE的,5ms 就能让平均锁等待翻倍
复杂逻辑让错误和性能问题完全逃逸监控体系
EXPLAIN INSERT INTO orders 不会展示触发器内任何语句;slow_query_log 只记主 SQL,不标触发器名;ERROR 1442: Can't update table 't1' in stored function/trigger 这类报错,根本不会告诉你哪条触发器、哪一行代码惹的祸。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 想定位耗时?只能翻
performance_schema.events_statements_history_long,但SQL_TEXT默认截断,长逻辑得人工拼 -
SHOW CREATE TRIGGER查定义要手动执行,没法集成进告警或巡检脚本 - 多个触发器争抢同一张统计表(如
user_summary)主键 → 高概率出现Deadlock found when trying to get lock
复杂逻辑天然破坏高并发写入吞吐能力
MySQL 触发器是行级、同步、逐行调用的。1 条 INSERT 触发 1 次,1000 行就是 1000 次——没有异步、不能批处理、绕不开事务边界。
-
LOAD DATA INFILE带触发器?性能衰减线性增长,索引优化完全无效 - 触发器数量超几十个时,
metadata lock等待明显上升,连ALTER TABLE都可能被卡住 - 跨库查询(如
SELECT * FROM other_db.users)会引入额外连接与网络延迟,且无法利用当前事务上下文
最麻烦的不是“能不能写”,而是“出问题时你根本看不到它在干啥”。只要逻辑稍复杂、并发一上来、数据量一涨,它就立刻拖垮写入性能,而且你在慢日志、监控大盘、链路追踪里都找不到它的影子。










