Tengo un activador ACTUALIZAR en una tabla que vigila una columna específica que cambia de un valor específico a cualquier otro valor. Cuando esto sucede, actualiza algunos datos relacionados en otra tabla a través de una sola instrucción UPDATE.
Lo primero que hace el disparador es verificar si alguna fila actualizada tuvo el valor de esta columna cambiado del valor en cuestión. Simplemente se une INSERTED a DELETED y compara el valor en esa columna. Si nada califica, se rescata temprano para que la instrucción UPDATE no se ejecute.
IF NOT EXISTS (
SELECT TOP 1 i.CUSTNMBR
FROM INSERTED i
INNER JOIN DELETED d
ON i.CUSTNMBR = d.CUSTNMBR
WHERE d.CUSTCLAS = 'Misc'
AND i.CUSTCLAS != 'Misc'
)
RETURN
En este caso, CUSTNMBR es la clave principal de la tabla subyacente. Si hago una gran actualización en esta tabla (por ejemplo, más de 5000 filas), esta declaración toma EDADES, incluso si no he tocado la columna CUSTCLAS. Puedo ver cómo se detiene en esta declaración durante varios minutos en Profiler.
El plan de ejecución es extraño. Muestra una exploración insertada con 3.714 ejecuciones y ~ 18,5 millones de filas de salida. Eso se ejecuta a través de un filtro en la columna CUSTCLAS. Lo une (a través de un bucle anidado) a un Análisis eliminado (también filtrado en CUSTCLAS), que se ejecuta solo una vez y tiene 5000 filas de salida.
¿Qué idiota estoy haciendo aquí para causar esto? Tenga en cuenta que el desencadenante absolutamente debe manejar correctamente las actualizaciones de varias filas.
EDITAR :
También intenté escribirlo así (en caso de que EXISTS estuviera haciendo algo desagradable), pero sigue siendo igual de terrible.
DECLARE @CUSTNMBR varchar(31)
SELECT TOP 1 @CUSTNMBR = i.CUSTNMBR
FROM INSERTED i
INNER JOIN DELETED d
ON i.CUSTNMBR = d.CUSTNMBR
WHERE d.CUSTCLAS = 'Misc'
AND i.CUSTCLAS != 'Misc'
IF @CUSTNMBR IS NULL
RETURN