很可能,[Data_trigger]
和inserted
之間的連接使用上[Data_trigger]
表TABLE SCAN/CLUSTERED INDEX SCAN
。
你能做些什麼?
此觸發器檢查緩存計劃:
1)首先,運行此查詢找到plan_handle
爲對象(觸發):
SELECT t.name AS TriggerName
,ts.*
FROM sys.dm_exec_trigger_stats ts
INNER JOIN sys.triggers t ON ts.object_id = t.object_id
WHERE ts.database_id = DB_ID()
AND t.name LIKE '%Audit%';
2)其次,找到緩存計劃(XML) 。例如,如果對於此觸發器的計劃句柄爲0x050009009A0A677BB8E09C7A000000000000000000000000
,你可以使用這個查詢來查找高速緩存的計劃:
DECLARE @plan_handle VARBINARY(64) = 0x050009009A0A677BB8E09C7A000000000000000000000000;
SELECT *
FROM sys.dm_exec_query_plan(@plan_handle) qp;
如果[Data_trigger]
和inserted
之間的連接使用CLUSTERED INDEX SCAN
爲[Data_trigger]
那麼你(至少)三SQL Server 2008
中的選項:
1)UPDATE STATISTICS
on [Data_trigger]
表:updating statistics causes queries to recompile。這種操作,測試觸發並再次檢查高速緩存的計劃,看它是否使用SEEK
後。
2)或者,你可以使用一個子查詢IN
從重寫的UPDATE
JOIN
:
FROM
[Data_Trigger] data
WHERE data.DataID IN (SELECT DataID IN SELECT inserted)
此操作,測試觸發後並再次檢查高速緩存的計劃,看它是否使用SEEK
。
3)如果SEEK
手術者沒有使用,那麼你可以use FORCESEEK
table hint (new in SQL Server 2008
; also see Best Practice Considerations section):
FROM
[Data_Trigger] data WITH(FORCESEEK)
JOIN
inserted ON data.DataID = inserted.DataID
對於TABLE SCAN
嘗試創建一個唯一的(羣集或羣集)指數DataID
列。
你需要知道的是,修改實際發生的日期時間,或者您使用此爲某種機制來協調一些進一步的活動(如別的東西跟蹤'MAX(DateLastUpdated)'它最後一次見到,然後請求行具有更大的'DateLastUpdated') - 如果第二,你可以使用'rowversion',這是由SQL Server自動維護。 –