मुझे एक टेबल पर एक UPDATE ट्रिगर मिला है जो एक विशिष्ट कॉलम के लिए एक विशिष्ट मूल्य से किसी अन्य मूल्य के लिए देखता है। जब ऐसा होता है, यह एक अद्यतन तालिका के माध्यम से किसी अन्य तालिका में कुछ संबंधित डेटा को अद्यतन करता है।
ट्रिगर करता है पहली बात यह देखने के लिए है कि क्या किसी भी अद्यतन पंक्तियों में इस स्तंभ का मान प्रश्न में मान से बदला गया था। यह केवल DELETED में शामिल हो जाता है और उस कॉलम में मूल्य की तुलना करता है। यदि कुछ भी योग्य नहीं है, तो यह जल्दी बाहर निकल जाता है ताकि अद्यतन विवरण न चले।
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
इस मामले में, CUSTNMBR अंतर्निहित तालिका की प्राथमिक कुंजी है। यदि मैं इस तालिका (5000+ पंक्तियों) पर एक बड़ा अपडेट करता हूं, तो यह कथन AGES लेता है, भले ही मैंने CUSTCLAS कॉलम को नहीं छुआ हो। मैं इसे इस विवरण पर प्रोइलर में कई मिनटों तक देख सकता हूं।
निष्पादन योजना विचित्र है। यह 3,714 निष्पादन, और ~ 18.5 मिलियन आउटपुट पंक्तियों के साथ एक सम्मिलित स्कैन दिखाता है। यह CUSTCLAS कॉलम पर एक फिल्टर के माध्यम से चलता है। यह इसे (नेस्टेड लूप के माध्यम से) हटाए गए स्कैन (CUSTCLAS पर भी फ़िल्टर किया गया) से जुड़ता है, जो केवल एक बार निष्पादित होता है और जिसमें 5000 आउटपुट पंक्तियाँ होती हैं।
इसका कारण क्या है? ध्यान दें कि ट्रिगर को बहु-पंक्ति अपडेट को ठीक से संभालना चाहिए।
संपादित करें :
मैंने इसे इस तरह से लिखने की कोशिश भी की (मामले में EXISTS कुछ अप्रिय कर रहा था), लेकिन यह अभी भी उतना ही भयानक है।
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