किसी भी विचार क्यों IF EXISTS
यह इतना लंबे समय तक चलेगा और इतने अधिक पढ़ेगा? मैंने करने के लिए चुनिंदा बयान भी बदले SELECT TOP 1 [dlc].[id]
और मैंने 2 मिनट के बाद इसे मार दिया।
जैसा कि मैंने इस संबंधित प्रश्न के उत्तर में बताया:
कैसे और क्यों) TOP एक निष्पादन योजना को प्रभावित करता है?
EXISTS
एक पंक्ति लक्ष्य का उपयोग करना , जहां ऑप्टिमाइज़र पहली पंक्ति को जल्दी से पता लगाने के उद्देश्य से एक निष्पादन योजना बनाता है। ऐसा करने में, यह मानता है कि डेटा समान रूप से वितरित किया गया है। उदाहरण के लिए, यदि आंकड़े बताते हैं कि 100,000 पंक्तियों में 100 अपेक्षित मैच हैं, तो यह मान लेगा कि पहला मैच खोजने के लिए इसे केवल 1,000 पंक्तियों को पढ़ना होगा।
यह अपेक्षित निष्पादन समय से अधिक समय के लिए परिणाम देगा यदि यह धारणा दोषपूर्ण हो। उदाहरण के लिए, यदि SQL सर्वर एक एक्सेस मेथड (जैसे अनऑर्डर्ड स्कैन) चुनता है, जो कि सर्च में बहुत देर से पहली मैचिंग वैल्यू का पता लगाने के लिए होता है, तो यह लगभग पूरा स्कैन हो सकता है। दूसरी ओर, यदि एक मिलान पंक्ति पहले कुछ पंक्तियों के बीच पाई जाती है, तो प्रदर्शन बहुत अच्छा होगा। यह पंक्ति लक्ष्यों के साथ मौलिक जोखिम है - असंगत प्रदर्शन।
एक अस्थायी फिक्स के रूप में मैंने इसे एक काउंट (*) करने के लिए बदल दिया है और उस मान को एक वैरिएबल पर असाइन किया है
आमतौर पर क्वेरी को सुधारना संभव है जैसे कि एक पंक्ति लक्ष्य असाइन नहीं किया गया है। पंक्ति लक्ष्य के बिना, क्वेरी तब भी समाप्त हो सकती है जब पहली मिलान पंक्ति का सामना किया गया हो (यदि सही तरीके से लिखा गया हो), लेकिन निष्पादन योजना की रणनीति अलग होने की संभावना है (और उम्मीद है, अधिक प्रभावी)। जाहिर है, गिनती (*) को सभी पंक्तियों को पढ़ने की आवश्यकता होगी, इसलिए यह एक सही विकल्प नहीं है।
यदि आप SQL Server 2008 R2 या उसके बाद चल रहे हैं, तो आप पंक्ति लक्ष्य के बिना निष्पादन योजना प्राप्त करने के लिए आमतौर पर प्रलेखित और समर्थित ट्रेस ध्वज 4138 का उपयोग कर सकते हैं । इस ध्वज को समर्थित संकेत का उपयोग करके भी निर्दिष्ट किया जा सकता है OPTION (QUERYTRACEON 4138)
, हालांकि यह ध्यान रखें कि यह एक योजना मार्गदर्शिका के साथ उपयोग किए जाने तक क्रम सिस्मैडिन अनुमति की आवश्यकता होती है ।
दुर्भाग्य से
उपरोक्त में से कोई भी एक IF EXISTS
सशर्त विवरण के साथ कार्यात्मक नहीं है । यह केवल नियमित डीएमएल पर लागू होता है। यह आपके द्वारा किए गए वैकल्पिक सूत्रीकरण के साथ काम करेगाSELECT TOP (1)
। यह प्रयोग करने से बेहतर हो सकता है COUNT(*)
, जिसे पहले बताई गई सभी योग्य पंक्तियों को गिनना है।
उस ने कहा, इस आवश्यकता को व्यक्त करने के लिए कई तरीके हैं जो आपको खोज को जल्दी समाप्त करते हुए पंक्ति लक्ष्य से बचने या नियंत्रित करने की अनुमति देंगे। एक अंतिम उदाहरण:
DECLARE @Exists bit;
SELECT @Exists =
CASE
WHEN EXISTS
(
SELECT [dlc].[ID]
FROM TableDLC [dlc]
JOIN TableD [d]
ON [d].[ID] = [dlc].[ID]
JOIN TableC [c]
ON [c].[ID] = [d].[ID2]
WHERE [c].[Name] <> [dlc].[Name]
)
THEN CONVERT(bit, 1)
ELSE CONVERT(bit, 0)
END
OPTION (QUERYTRACEON 4138);
IF @Exists = 1
BEGIN
...
END;
IF NOT EXISTS (...) BEGIN END ELSE BEGIN <do something> END
।