Очень вероятно, что соединение между [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
колонка.