【发布时间】:2015-08-03 09:07:20
【问题描述】:
问题陈述
我有一个从 3 个不同的大表到超大表递归收集和聚合信息的视图。此视图本身需要相当长的时间来执行,但在许多 select 语句中都需要并且经常执行。
但是,生成的视图非常小(2 列中有几十个结果)。
所有更新操作通常会启动一个事务,执行数千个 INSERT,然后提交该事务。这种情况不会经常发生,但如果将某些内容写入数据库,则通常是大量数据。
我尝试了什么
- 由于视图很小,不经常变化,经常阅读,我想到了创建一个索引视图。但是,遗憾的是,您无法使用 CTE 甚至递归 CTE 创建索引视图。
- 为了“模拟”索引或物化视图,我考虑编写一个触发器,该触发器在每次修改一个基表时执行视图并将结果存储到一个表中。但是,我想如果大量条目被更新或插入并且触发器针对这些表上的每个 INSERT/UPDATE 语句运行,即使它们在单个事务中,这将永远需要。
实际问题
是否可以编写一个触发器,该触发器在提交之前和事务的最后一个插入/更新语句完成之后运行一次,并且仅当任何语句更改了三个表中的任何一个时才运行?
【问题讨论】:
-
直接,不,触发器每个触发语句运行一次。间接地,您可以将所有 INSERT 插入到临时表中,然后将它们一起从 #temp 表插入到真实表中,从而为该表触发一个触发器。但是,如果您要写入多个表,您仍然会遇到同样的问题。解决此问题的 SOP 方法是让存储过程在前面处理所有内容,而不是让 Trigger 试图在后端捕获所有内容。
-
修改基表时,是使用单个 INSERT 或 UPDATE 语句影响多行还是使用了许多粒度语句?
-
好吧,您可以编写触发器来记录每个表中的每次数据更改。然后编写一个作业,每隔几分钟左右检查一次任何更改,并相应地使用您的视图更新表。这样它就不会触发太多次,但您的数据在一定时间内是最新的。
-
@Ben Gribaudo:有很多细粒度的语句,即将几千条记录作为一个“批处理”事务插入到一张表中。
-
@Stephan:感谢您的想法,但在此应用程序中,数据一致性至关重要。数据必须始终保持一致,因此与每个事务的提交一致。不幸的是,这里不可能采用“最终一致”的方法。
标签: sql sql-server sql-server-2008 tsql triggers