Sql server 2005 插入/删除的触发器表上的慢速联接

Sql server 2005 插入/删除的触发器表上的慢速联接,sql-server-2005,triggers,Sql Server 2005,Triggers,我们有一个触发器,它为一个表创建审计记录,并连接插入的表和删除的表,以查看是否有任何列发生了更改。联接在小集合中一直运行良好,但现在我正在更新大约100万行,并且它不会在几天内完成。我尝试用不同的数量级更新选定数量的行,很明显这是指数型的,如果扫描插入/删除的表以进行连接,这是有意义的 我尝试创建索引,但出现错误: 找不到插入的对象,因为它不存在或您没有权限 有什么方法可以让这更快吗?插入到连接列上索引的临时表中可以很好地改善情况,因为插入和删除都没有索引 您可以检查触发器内的@@ROWCOUN

我们有一个触发器,它为一个表创建审计记录,并连接插入的表和删除的表,以查看是否有任何列发生了更改。联接在小集合中一直运行良好,但现在我正在更新大约100万行,并且它不会在几天内完成。我尝试用不同的数量级更新选定数量的行,很明显这是指数型的,如果扫描插入/删除的表以进行连接,这是有意义的

我尝试创建索引,但出现错误: 找不到插入的对象,因为它不存在或您没有权限


有什么方法可以让这更快吗?

插入到连接列上索引的临时表中可以很好地改善情况,因为插入和删除都没有索引

您可以检查触发器内的@@ROWCOUNT,这样您只能在某些阈值行数以上执行此逻辑,但在SQL Server 2008上,如果触发器是由于MERGE语句触发的,则这可能会在某种程度上夸大该行数。它将返回受所有合并操作影响的行总数,而不仅仅是与该合并操作相关的行数特定触发器

在这种情况下,您可以执行类似于从插入的T中选择TOP 10*中选择@NumRows=COUNT*的操作,以查看是否满足阈值

加成

您可以尝试的另一种可能性是绕过这些大型更新的触发器。您可以使用SET CONTEXT_INFO设置一个标志,并在触发器内检查该标志的值。然后可以使用输出inserted.*、deleted.*获取行的before和after值,而无需任何连接


我只是想将它们中的每一个选择到新的临时表中,然后我就可以创建索引了。然而,我也担心个人记录的性能,这似乎有点过头了。@Martin-现在是2005年,我刚刚更新了标签以反映这一点。设置阈值的要点很好。这可能会使触发变得相当复杂,但我认为任何事情都有权衡的余地。我仍然对一件事感到困惑:我们有另一个几乎相同的数据库,它没有经历这种减速。表、触发器和索引看起来是相同的,尽管我还没有做详细的比较。
DECLARE @TriggerFlag varbinary(128)
SET @TriggerFlag = CAST('Disabled' AS varbinary(128)) 

SET CONTEXT_INFO @TriggerFlag

UPDATE YourTable
SET Bar = 'X'
OUTPUT inserted.*, deleted.* INTO @T

/*Reset the flag*/
SET CONTEXT_INFO 0x