更新触发器以跟踪上次更新日期(SQL 2008 R2)

时间:2011-10-12 23:58:58

标签: sql-server sql-server-2008 triggers

我正在寻找一个模型,用于保留一组表中所有记录的最后更新时间戳。一个想法是使用触发器实现它,这样无论记录如何更新,DateLastUpdated列都将保持最新。

给定一个名为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

1 个答案:

答案 0 :(得分:4)

[Data_trigger]inserted之间的联接很可能在TABLE SCAN/CLUSTERED INDEX SCAN表上使用了[Data_trigger]

你能做什么?

检查此触发器的缓存计划:

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 [Data_trigger]表上的SEEKupdating statistics causes queries to recompile。执行此操作后,测试触发器并再次检查缓存计划以查看它是否使用JOIN

2)或者,您可以使用一个UPDATE子查询从IN重写FROM [Data_Trigger] data WHERE data.DataID IN (SELECT DataID IN SELECT inserted)

SEEK

执行此操作后,测试触发器并再次检查缓存计划,看它是否使用SEEK

3)如果未使用FROM [Data_Trigger] data WITH(FORCESEEK) JOIN inserted ON data.DataID = inserted.DataID 运算符,则可以use FORCESEEK table hint (new in SQL Server 2008; also see Best Practice Considerations section)

TABLE SCAN

DataID尝试在{{1}}列上创建唯一(群集或群集)索引。