我有一个从3个不同的大表到非常大的表递归收集和聚合信息的视图。此视图本身需要相当长的时间来执行,但在许多select语句中需要并且经常执行。
然而,生成的视图非常小(2列中有一些dozend结果)。
所有更新操作通常都会启动一个事务,执行数千个INSERT,然后提交事务。这种情况不会经常发生,但如果将某些内容写入数据库,则通常会有大量数据。
我尝试了什么
是否有可能在提交之前和事务的最后一次插入/更新语句完成之后编写一个一次的触发器,并且只有当任何一个语句改变了这三个表中的任何一个时?
答案 0 :(得分:3)
不,没有直接的方法来制作在交易结束前运行的触发器。每次触发DML语句(INSERT
,UPDATE
,DELETE
)时,DML触发器运行一次,并且没有其他类型的触发器与数据修改相关。
间接地,您可以将所有INSERT插入到临时表中,然后将它们从#temp表中一起插入到真实表中,从而导致该表触发一个触发器。但是如果你要写多个表,你仍会遇到同样的问题。
SOP(标准操作实践)解决此问题的方法是让存储过程预先处理所有事情,而不是尝试捕获背面的所有内容的触发器。
如果数据一致性很重要,那么我建议您遵循上面提到的存储过程中的SOP方法。以下是这种方法的高级概述:
这几乎总是如此正确地完成这样的事情。
答案 1 :(得分:1)
如果您的视图很小并且经常查询并且您的下划线表很少更改,则您不需要“视图”。相反,您需要一个具有相同视图结果的摘要表,并通过每个下划线表上的触发器进行更新。
每次进行数据修改(插入,删除和更新)时都会触发触发器,但一次修改只会触发一次,无论是更新一个记录还是一百万行。您无需担心更新的大小。相反,更新的频率是您的关注点。
如果您的程序定期插入大量行或逐行更新大量行,则可以在更新之前更改过程并禁用触发器,以便仅在过程结束之前更新摘要表,您可以在其中调用相同的“总和”过程并启用这些触发器。
如果您必须始终保持“摘要”最新,即使在大量交易中(我怀疑它是非常有用或实际的,如果您的视图执行缓慢),您可以禁用这些触发器,在每次交易后自己做一些计算,在每个交易后,在你的程序中更新汇总表。