2011-10-12 97 views
0

我正在尋找的正常運轉,所有記錄的最後更新時間戳在一組表的典範。一個想法是使用觸發器實現這一點,以便無論記錄如何更新,DateLastUpdated列都會保持最新。更新觸發追蹤上次更新日期(SQL 2008 R2)

給定一個測試表叫Data_Updata,這是我當前的更新觸發確保 更新數據。當我運行這個查詢查詢執行計劃時,觸發器佔用了56%的時間。是否有更有效的觸發器/ SQL使用?

ALTER TRIGGER [dbo].[Data_Update] 
    ON [dbo].[Data_Trigger] 
    FOR UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 
    UPDATE 
     [Data_Trigger] 
    SET 
     DateLastUpdated = GetDate() 
    FROM 
     [Data_Trigger] data 
    JOIN 
     inserted ON data.DataID = inserted.DataID 
END 
+0

你需要知道的是,修改實際發生的日期時間,或者您使用此爲某種機制來協調一些進一步的活動(如別的東西跟蹤'MAX(DateLastUpdated)'它最後一次見到,然後請求行具有更大的'DateLastUpdated') - 如果第二,你可以使用'rowversion',這是由SQL Server自動維護。 –

回答

4

很可能,[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從重寫的UPDATEJOIN

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列。