नहीं बचा जाना चाहिए?


14

कुछ SQL सर्वर डेवलपर्स के बीच, यह एक व्यापक रूप से आयोजित विश्वास है NOT INजो बहुत धीमी गति से है , और प्रश्नों को फिर से लिखा जाना चाहिए ताकि वे एक ही परिणाम लौटाएं लेकिन "बुराई" कीवर्ड का उपयोग न करें। ( उदाहरण )।

क्या इसमें कोई सच्चाई है?

उदाहरण के लिए, SQL सर्वर में कुछ ज्ञात बग (कौन सा संस्करण?) जो क्वेरी का उपयोग करते हुए NOT INएक समान क्वेरी की तुलना में एक बदतर निष्पादन योजना का उपयोग करता है।

  • एक चेक LEFT JOINके साथ संयुक्त NULLया
  • (SELECT COUNT(*) ...) = 0में WHEREखंड?

7
हालांकि यह लेख बेहद गलत है। "में" नहीं है और TableOne में प्रत्येक पंक्ति के लिए एक ही क्वेरी को बार-बार चलाना पड़ता है। वहाँ पोस्टर लगता है कि IN/ NOT INहमेशा नेस्टेड छोरों के साथ लागू किया जाएगा। और मुझे नहीं पता कि क्या stops SQL Server from creating a ‘plan’मतलब है।
मार्टिन स्मिथ

5
@ हिनजी आप जिस लेख से जुड़ते हैं, उसे आग में मर जाना चाहिए, यह बकवास से भरा है। जैसे: "IN को बदलने के लिए, हम एक INNER JOIN का उपयोग करते हैं। वे प्रभावी रूप से एक ही चीज हैं।" समस्या यह है, वे एक ही चीज नहीं हैं। मैं किसी ऐसे व्यक्ति पर भरोसा नहीं करूंगा, जो SQL- सर्वर व्यवहार के बारे में कुछ भी विश्लेषण करने के लिए बुनियादी एसक्यूएल, यानी एक जॉइन और सेमी-जॉइन के बीच का अंतर नहीं जानता।
ypercube y

जवाबों:


14

मुझे नहीं लगता कि यह बहुत धीमी गति से होने के साथ कुछ भी करना है; यह संभावित रूप से गलत होने के साथ करना है। उदाहरण के लिए, निम्नलिखित डेटा दिए गए हैं - आदेश जो किसी व्यक्तिगत ग्राहक या बी 2 बी भागीदार द्वारा रखे जा सकते हैं:

DECLARE @Customers TABLE(CustomerID INT);

INSERT @Customers VALUES(1),(2);

DECLARE @Orders TABLE(OrderID INT, CustomerID INT, CompanyID INT);

INSERT @Orders VALUES(10,1,NULL),(11,NULL,5);

मान लीजिए कि मैं उन सभी ग्राहकों को खोजना चाहता हूं जिन्होंने कभी ऑर्डर नहीं दिया है। डेटा को देखते हुए, केवल एक ही है: ग्राहक # 2। इस जानकारी को खोजने के लिए क्वेरी लिखने के बारे में मैं यहां तीन तरीके बता सकता हूं (अन्य हैं):

SELECT [NOT IN] = CustomerID FROM @Customers 
  WHERE CustomerID NOT IN (SELECT CustomerID FROM @Orders);

SELECT [NOT EXISTS] = CustomerID FROM @Customers AS c 
  WHERE NOT EXISTS (SELECT 1 FROM @Orders AS o
  WHERE o.CustomerID = c.CustomerID);

SELECT [EXCEPT] = CustomerID FROM @Customers
EXCEPT SELECT CustomerID FROM @Orders;

परिणाम:

NOT IN
------
                 -- <-- no results. Is that what you expected?

NOT EXISTS
----------
2

EXCEPT
------
2

अब, कुछ प्रदर्शन मुद्दे भी हैं, और मैं इस ब्लॉग पोस्ट में उनके बारे में बात करता हूं । डेटा और इंडेक्स के आधार पर, NOT EXISTSआमतौर पर बेहतर प्रदर्शन करेगा NOT IN, और मुझे नहीं पता कि क्या यह कभी भी खराब प्रदर्शन कर सकता है। आपको यह भी ध्यान देना चाहिए कि EXCEPTएक अलग प्रकार का ऑपरेशन शुरू कर सकता है, इसलिए आप अलग-अलग डेटा (फिर से, स्रोत पर निर्भर करता है) के साथ समाप्त हो सकते हैं। और यह कि लोकप्रिय LEFT OUTER JOIN ... WHERE right.column IS NULLपैटर्न हमेशा सबसे खराब प्रदर्शन करने वाला होता है।

मार्टिन स्मिथ ने एसओ पर अपने जवाब में बहुत अच्छी सहायक जानकारी दी है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.