Вставка во временные таблицы, проиндексированные в соединяющихся столбцах, может улучшить ситуацию, поскольку inserted
и deleted
не проиндексированы.
Вы можете проверить @@ROWCOUNT
внутри триггера, чтобы выполнять эту логику только над некоторым пороговым числом строк, хотя в SQL Server 2008 это может несколько завышать число, если триггер был запущен в результате выполнения оператора MERGE
( Он вернет общее количество строк, на которые влияют все действия MERGE
, а не только те, которые относятся к этому конкретному триггеру.
В этом случае вы можете просто сделать что-то вроде SELECT @NumRows = COUNT(*) FROM (SELECT TOP 10 * FROM INSERTED) T
, чтобы увидеть, достигнут ли порог.
Сложение
Еще одна возможность, с которой вы можете поэкспериментировать, - это просто обойти триггер для этих больших обновлений. Вы можете использовать SET CONTEXT_INFO
, чтобы установить флаг и проверить значение этого внутри триггера. Затем вы можете использовать OUTPUT inserted.*, deleted.*
, чтобы получить значения «до» и «после» для строки без необходимости JOIN
.
DECLARE @TriggerFlag varbinary(128)
SET @TriggerFlag = CAST('Disabled' AS varbinary(128))
SET CONTEXT_INFO @TriggerFlag
UPDATE YourTable
SET Bar = 'X'
OUTPUT inserted.*, deleted.* INTO @T
/*Reset the flag*/
SET CONTEXT_INFO 0x