我想知道在每次插入表后执行更新的触发器是否比在插入查询后手动执行更新查询要慢。
答案 0 :(得分:4)
就 PostgreSQL 而言:
一次插入/更新一行,几乎。虽然 - 不一定是因为@Michael所说的网络开销 - 您可以将INSERT
和 UPDATE
打包到一个查询中。考虑writeable CTEs。
要一次插入/更新多行或多行,是, 可能会慢得多。在单个命令中处理许多行要便宜得多,因此x行的一个UPDATE比触发器启动的x个别更新要便宜得多。
但是,没有什么可以肯定的,因为许多其他因素起作用。我引用了the manual here:
PostgreSQL提供每行触发器和每个语句触发器。 使用每行触发器,为每个触发器函数调用一次 触发触发器的语句受影响的行。
大胆强调我的。
答案 1 :(得分:3)
这取决于多种因素。首先,您已经为三种完全不同的数据库产品标记了这一点。这三个人的答案可能不同。
仅考虑Oracle,它取决于您要影响的行数以及这是否是表中唯一的触发器。如果您的INSERT
语句插入数千行,并且这将是表上的唯一触发器,则创建触发器会强制数千个SQL转换为PL / SQL上下文并强制运行数千个UPDATE
语句。如果您在没有触发器后跟单个INSERT
的表中执行了单个UPDATE
,则无需执行所有这些上下文转换,并且您的UPDATE
语句可能可以使用一个更适合修改数千行但不只是一行的计划。另一方面,如果您的INSERT
语句插入单行,则性能差异可能很小,因为您更喜欢UPDATE
语句的单行计划而且您已经只做一组上下文转换。
当然,从架构的角度来看,可能还有其他问题。从A上的行级触发器更新表B通常很难在多用户环境中正确执行。在触发器中绑定了很多这样的逻辑往往会使系统变得非常不稳定 - 这使得开发人员难以通过代码来掌握变更的影响,这些变更经常导致神秘的错误和不一致。它还经常导致你有一系列插入和更新由一系列触发器生成的最终导致变异表异常的情况,因为表A上的插入修改了B,它修改了C,你有一个触发器转向并查询A 。如果您需要维护某种汇总值(即,当某人修改order_total
中的某行时,您尝试更新orders
表的order_items
列),那么物化视图可能是更合适的架构解决方案。或者,您可能会更好地通过表格中的虚拟列或带有计算的视图来提供服务。
答案 2 :(得分:1)
简而言之,不可能是因为触发器的执行计划已经编译完毕。此外,它是语句的原生,因此发送语句时没有网络延迟。
答案 3 :(得分:0)
这是一个复杂的问题,答案很可能取决于数据库。
一般情况下,我认为触发器至少与仅涉及一行时执行单独更新一样快。但是,插入多行时情况可能会有所不同。在这种情况下,某些数据库会使用多行调用触发器一次。有些数据库多次调用触发器,每行调用一次。
在后一种情况下,您可以通过同时执行多个操作来获得更快的代码。
另一个考虑因素是吞吐量。使用触发器的操作可能更快。但是,它也可能会将表或行锁定更长的时间,从而阻止对表执行其他操作。您可能会发现交错式数据库调用比较长的数据库调用要快。
如果你问这样的问题,我的建议是你做时间安排。不要指望不同数据库的结果是相同的。虽然数据库引擎有很多共同之处,但这涉及锁定和事务的细节,这些细节在供应商之间有所不同。