0

我想知道在表中每次插入后执行更新的触发器是否比在插入查询后手动执行更新查询慢。

4

4 回答 4

4

PostgreSQL而言:

对于一次插入/更新一行,几乎没有. 虽然-不一定是因为@Michael认为的网络开销-您可以打包INSERT UPDATE放入单个查询中。考虑可写 CTE

对于一次插入/更新多行或多行,YES,它可能会相当慢。在单个命令中处理许多行要便宜得多,因此 x 行的一次 UPDATE 将比触发器启动的 x 个单独更新便宜得多。

但是,没有什么可以肯定地说,因为许多其他因素也起作用。

我在这里引用手册

PostgreSQL 提供每行触发器和每语句触发器。对于每行触发器,对于受触发触发器的语句影响的每一行,都会调用一次触发器函数。

大胆强调我的。

于 2013-07-23T00:07:24.393 回答
3

这取决于多种因素。首先,您已经为三个完全不同的数据库产品标记了它。这三个人的答案可能不同。

仅考虑 Oracle,这取决于您影响的行数以及这是否是表上的唯一触发器。如果您的INSERT语句插入了数千行并且这将是表上唯一的触发器,那么创建触发器会强制将数千个 SQL 转换为 PL/SQL 上下文并强制UPDATE运行数千个语句。如果您在一个INSERT没有触发器的表中执行了一个单一的UPDATE操作,那么您将无需进行所有这些上下文转换,并且您的UPDATE语句可能能够使用更适合修改数千行而不是仅一个行的计划排。另一方面,如果您的INSERT语句插入单行,性能差异可能很小,因为您更喜欢该语句的单行计划,UPDATE并且您只会执行一组上下文转换。

当然,从架构的角度来看,可能还有其他问题。在多用户环境中,从 A 上的行级触发器更新表 B 通常很难正确完成。将大量此类逻辑绑定在触发器中往往会使系统变得非常不稳定——这使得开发人员很难通过代码来掌握经常导致神秘错误和不一致的更改的影响。它还经常导致您有由一系列触发器生成的长链插入和更新,这些触发器最终导致变异表异常,因为表 A 上的插入修改了 B,而 B 修改了 C,而您有一个翻转并查询 A 的触发器. 如果您需要维护某种汇总值(即您正在尝试order_total更新orders表中的一行修改order_items),物化视图可能是更合适的架构解决方案。或者,表中的虚拟列或带有计算的视图可能会更好地为您服务。

于 2013-07-23T00:05:32.420 回答
1

简而言之,不可能是因为触发器的执行计划被编译了。此外,它是语句本身的,因此发送语句没有网络延迟。

于 2013-07-22T23:46:27.347 回答
0

这是一个复杂的问题,答案可能取决于数据库。

一般来说,当只涉及一行时,我希望触发器至少与单独更新一样快。但是,当插入多行时,情况可能会有所不同。在这种情况下,某些数据库会使用多行调用一次触发器。一些数据库多次调用触发器,每行一次。

在后一种情况下,您可以通过同时执行多个操作来获得更快的代码。

另一个考虑因素是吞吐量。使用触发器的操作可能会更快。但是,它也可能将表或行锁定更长的时间,从而阻止对表的其他操作。您可能会发现交错的数据库调用比较长的数据库调用更快。

如果你问这样的问题,我的建议是你做计时。不要期望不同数据库的结果相同。尽管数据库引擎有很多共同点,但这是处理锁定和事务的细节,这在供应商之间确实有所不同。

于 2013-07-23T00:08:31.873 回答