Триггер обновления для отслеживания даты последнего обновления (SQL 2008 R2) - PullRequest
0 голосов
/ 13 октября 2011

Я ищу модель для хранения отметки времени последнего обновления для всех записей в наборе таблиц. Одна идея заключалась в том, чтобы реализовать это с помощью триггеров, чтобы независимо от того, как обновлялась запись, столбец 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 Ответ

4 голосов
/ 13 октября 2011

Очень вероятно, что соединение между [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]: обновление статистики приводит к перекомпиляции запросов .После этой операции протестируйте триггер и снова проверьте кэшированный план, чтобы увидеть, использует ли он SEEK.

2) Или вы можете переписать JOIN из UPDATE, используя один подзапрос IN:

FROM
    [Data_Trigger] data
WHERE data.DataID IN (SELECT DataID IN SELECT inserted)

После этой операции протестируйте триггер и снова проверьте кэшированный план, чтобы увидеть, использует ли он SEEK.

3) Если оператор SEEK не используется, вы можете использоватьFORCESEEK табличная подсказка (новое в SQL Server 2008; также см. Раздел «Рекомендации по применению») :

FROM
    [Data_Trigger] data WITH(FORCESEEK)
JOIN
    inserted ON data.DataID = inserted.DataID

Для TABLE SCAN попробуйте создать уникальный (кластеризованный или кластеризованный) индекс для DataIDколонка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...