我有一个关于MySQL触发器的问题,因为谷歌没有给我任何可用的结果。
让我们想象一下我需要INSERT
或UPDATE
进入MySQL表的情况,同时这个程序也被记录/审核到不同的表中,例如对INSERT
进行两次查询,我会这样做:
INSERT INTO `cars` (`brand`, `type`, `year`) VALUES ('Audi', 'A6', 2013);
然后接收新行的ID并执行插入日志表:
INSERT INTO `cars_log` (`car_id`, `brand`, `type`, `year`, `action`, `date`) VALUES (1954, 'Audi', 'A6', 2013, 'insert', NOW());
除了这个解决方案,我还可以只使用一个INSERT
/ UPDATE
查询(进入cars
)并定义触发AFTER INSERT
和AFTER UPDATE
的触发器这将自动插入我的日志数据。
问题是:从性能的角度来看什么是更好的解决方案?
其他问题:
INSERT
/ UPDATE
查询次数较少,或仅在负载较高时,这种性能差异(如果有)是否显着?答案 0 :(得分:1)
使用触发器不会显着影响执行速度 - 最后,数据库系统正在执行相同的操作。
但是如果你确定每个INSERT
都要求更新,那么触发器是一个很好的方法
确保数据库完整性,所以一定要做到。
换句话说 - 触发器是实现任何类型的数据库更改跟踪的方法。但是,您需要了解使用触发器时发生的情况。
根据MySQL Stored Procedure Programming,“触发开销”标题下的第256页说明如下:
重要的是要记住,必要时,触发添加 它们适用的DML 语句的开销。实际金额 开销将取决于触发器的性质,但是 - 就像所有
MySQL
触发器执行FOR EACH ROW
---开销可以很快 累积处理大量行的语句。您 因此,应避免放置任何昂贵的 SQL语句或 触发器中的程序代码。
第529-531页给出了触发开销的扩展说明。该部分的结论点如下:
由于触发器代码将对受DML
语句影响的每一行执行一次,因此触发器很容易成为DML
性能中最重要的因素。触发器主体内部的代码需要尽可能轻量级,并且 - 特别是 - 只要有可能,索引应该支持触发器中的任何SQL语句。
使用触发器的另一件事 - 在审计日志记录方面,请注意您将数据记录到哪些内容。我之所以这样说,是因为如果您选择登录MyISAM
表格,INSERT
表格中的每个MyISAM
会在<{strong> INSERT
期间生成完整的表格锁定}。
这可能成为高流量,高交易环境中的严重瓶颈。此外,如果触发器针对InnoDB
表,并且您在触发器内记录MyISAM
中的更改,则会秘密禁用ACID
合规性(即,将块事务减少为自动提交行为),无法回滚。