Tôi đã có một trình kích hoạt CẬP NHẬT trên một bảng theo dõi một cột cụ thể thay đổi từ một giá trị cụ thể sang bất kỳ giá trị nào khác. Khi điều này xảy ra, nó cập nhật một số dữ liệu liên quan trong một bảng khác thông qua một câu lệnh CẬP NHẬT duy nhất.
Điều đầu tiên mà trình kích hoạt thực hiện là kiểm tra xem liệu có bất kỳ hàng cập nhật nào có giá trị của cột này thay đổi so với giá trị được đề cập hay không. Nó chỉ đơn giản là tham gia INSERTED để DELETED và so sánh giá trị trong cột đó. Nếu không có gì đủ điều kiện, nó sẽ giải cứu sớm để câu lệnh CẬP NHẬT không chạy.
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
Trong trường hợp này, CUSTNMBR là khóa chính của bảng bên dưới. Nếu tôi thực hiện một bản cập nhật lớn trên bảng này (giả sử, hơn 5000 hàng), tuyên bố này sẽ có LẠI, ngay cả khi tôi chưa chạm vào cột TÙY CHỈNH. Tôi có thể xem nó bị đình trệ trong tuyên bố này trong vài phút trong Profiler.
Kế hoạch thực hiện thật kỳ quái. Nó hiển thị Quét được chèn với 3.714 lần thực hiện và ~ 18,5 triệu hàng đầu ra. Điều đó chạy qua một bộ lọc trên cột CUSTCLAS. Nó kết hợp điều này (thông qua vòng lặp lồng nhau) với Quét đã xóa (cũng được lọc trên CUSTCLAS), chỉ thực hiện một lần và có 5000 hàng đầu ra.
Những điều ngu ngốc tôi đang làm ở đây để gây ra điều này? Lưu ý rằng kích hoạt hoàn toàn phải xử lý đúng cập nhật nhiều hàng.
CHỈNH SỬA :
Tôi cũng đã thử viết nó như thế này (trong trường hợp EXISTS đang làm điều gì đó khó chịu), nhưng nó vẫn tệ như vậy.
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