2011-10-13 102 views
3

我們有一個表中創建審計記錄並加入inserteddeleted表,看是否有列已經改變了觸發。這個連接對於小集合來說一直運行良好,但是現在我正在更新大約100萬行,並且在幾天內還沒有完成。我試着更新與不同量級行的選擇數量,很明顯這是指數,這將使意義,如果inserted/deleted表掃描做加盟。緩慢加入所插入/刪除觸發器表

我試圖創建一個索引,但得到的錯誤: Cannot find the object "inserted" because it does not exist or you do not have permissions.

有什麼辦法,使這個得更快?

+0

我只是想選擇每個這些到新的臨時表,之後我應該能夠創建索引。不過,我也關注對個人記錄的性能,這似乎矯枉過正那些。 –

+0

什麼版本的SQL Server? –

+0

@Martin - 這是2005年,我剛更新了標籤以反映這一點。 –

回答

4

插入到加入列索引的臨時表中可以改善事情,因爲inserteddeleted未編制索引。

您可以檢查@@ROWCOUNT觸發內,因此您只能執行上面的行某個閾值數這個邏輯雖然SQL Server 2008上,這可能誇大有點如果觸發被解僱的MERGE語句的結果數(這將返回受所有MERGE操作影響的行總數不只是與該特定觸發器相關的行總數)。

在這種情況下,您可以執行類似SELECT @NumRows = COUNT(*) FROM (SELECT TOP 10 * FROM INSERTED) T的操作,查看是否滿足閾值。其他

加成

一種可能性,你可以用簡單地繞過觸發這些大型更新實驗。您可以使用SET CONTEXT_INFO來設置一個標誌並檢查觸發器內部的值。然後,您可以使用OUTPUT inserted.*, deleted.*來獲取行的「之前」和「之後」值,根本不需要JOIN

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 
+0

設置閾值的重點。這可能會讓觸發器變得非常複雜,但我認爲對任何事情都有權衡。我仍然對一件事情感到困惑:我們有另一個幾乎相同的數據庫,它沒有經歷這種放緩。表,觸發器和索引似乎是相同的,但我還沒有做過詳細的比較。 –