调用两个INSERT / UPDATE查询或使用触发器调用一个查询更好吗?

时间:2014-05-22 11:38:14

标签: mysql triggers

我有一个关于MySQL触发器的问题,因为谷歌没有给我任何可用的结果。

让我们想象一下我需要INSERTUPDATE进入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 INSERTAFTER UPDATE的触发器这将自动插入我的日志数据。

问题是:从性能的角度来看什么是更好的解决方案?

其他问题:

  • 所有关系型DBMS的行为(性能问题)是否相同?
  • 即使INSERT / UPDATE查询次数较少,或仅在负载较高时,这种性能差异(如果有)是否显着?

1 个答案:

答案 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合规性(即,将块事务减少为自动提交行为),无法回滚。