क्या अंतर नहीं है, जो बनाम में नहीं है।


151

यह मुझे लगता है कि आप एक SQL क्वेरी में समान कार्य नहीं कर सकते हैं, न ही IN में, न ही लेफ्टिनेंट जॉइन कर सकते हैं। उदाहरण के लिए:

SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)

SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)

SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL

मुझे यकीन नहीं है कि मुझे सभी वाक्यविन्यास सही मिले, लेकिन ये सामान्य तकनीकें हैं जिन्हें मैंने देखा है। मैं एक का उपयोग दूसरे के लिए क्यों करना चाहूंगा? क्या प्रदर्शन अलग है ...? इनमें से कौन सा सबसे तेज / सबसे कुशल है? (यदि यह कार्यान्वयन पर निर्भर करता है, तो मैं हर एक का उपयोग कब करूंगा?)


6
कई सामान्य एसक्यूएल इंजन आपको एक निष्पादन योजना देखने की क्षमता देते हैं। आप अक्सर इस तरह से तार्किक प्रश्नों के लिए दक्षता में महत्वपूर्ण अंतर ला सकते हैं। किसी भी विधि की सफलता तालिका आकार जैसे कारकों पर निर्भर करती है, जो सूचकांक मौजूद हैं, और अन्य।
क्रिस किसान

2
@विच: कोई भी डेटाबेस इस बात की परवाह नहीं करता कि आप वास्तव में EXISTSक्लॉज़ के अंदर क्या कर रहे हैं । आप वापस आ सकते हैं *, NULLया जो भी: यह सब दूर अनुकूलित किया जाएगा।
कुआसानी

2
@विच - क्यों? दोनों यहाँ: techonthenet.com/sql/exists.php और यहाँ: msdn.microsoft.com/en-us/library/ms188336.aspx का उपयोग करने लगते हैं ...
18

8
@विच: यह "रुचि व्यक्त करने" के बारे में नहीं है। यह उस क्वेरी पार्सर के बारे में है जो आपको कुछ SELECTऔर के बीच रखने की मांग करता है FROM। और *टाइप करना आसान है। हां, SQLएक प्राकृतिक भाषा से मिलता जुलता है, लेकिन इसे एक मशीन, एक प्रोग्राम्ड मशीन द्वारा पार्स और निष्पादित किया जाता है। ऐसा नहीं है कि यह कभी भी आपके क्यूबिकल में टूट जाएगा और चिल्लाएगा "एक EXISTSक्वेरी में अतिरिक्त फ़ील्ड्स की मांग करना बंद कर दें क्योंकि मैं एफ ** जी उन्हें पार्स करने और फिर उन्हें फेंकने से बीमार हूं!"। यह कंप्यूटर के साथ ठीक है, वास्तव में।
क्वासोनी

1
@Quassnoi यदि आपने किसी मशीन के एकमात्र उद्देश्य के लिए कोड लिखा है तो यह कोड भयानक लगेगा, और दुर्भाग्य से काफी कुछ लोग इस तरह काम करते हैं। यदि आप कोड को दूसरे ऑप्टिक में लिखते हैं, तो यह लिखने के लिए कोड लिखते हैं कि आप अपने साथियों के लिए एक साम्य के रूप में क्या करना चाहते हैं, आप बेहतर और अधिक रखरखाव योग्य कोड लिखेंगे। स्मार्ट बनें, लोगों के लिए कोड लिखें, कंप्यूटर के लिए नहीं।
विच

जवाबों:


139

संक्षेप में:

NOT INथोड़ा अलग है: यह कभी मेल नहीं खाता है, लेकिन NULLसूची में एक भी है।

  • में MySQL, NOT EXISTSथोड़ा कम कुशल है

  • में SQL Server, LEFT JOIN / IS NULLकम कुशल है

  • में PostgreSQL, NOT INकम कुशल है

  • में Oracle, सभी तीन विधियां समान हैं।


1
लिंक के लिए धन्यवाद! और त्वरित अवलोकन के लिए धन्यवाद ... मेरा कार्यालय किसी कारण के लिए लिंक को अवरुद्ध कर रहा है: पी लेकिन मैं नियमित रूप से कंप्यूटर पर मिलते ही इसकी जांच करूंगा।
मेंढक

2
एक और बात यह है कि अगर है table1 .aशामिल क्वेरी इस पंक्ति लेकिन नहीं लौटेगा क्वेरी इच्छा करता है, तो खाली है। बनाम इन नॉट नॉट एक्सक्लूसिव कॉलम: एसक्यूएल सर्वरNULLEXISTSNOT INtable2
मार्टिन स्मिथ

@MartinSmith: NULL NOT IN ()सच का मूल्यांकन करता है (नहीं NULL), जैसा किNOT EXISTS (NULL = column)
क्वासोई

2
@Quassnoi - er, अच्छी बात है, कि गलत तरीका गोल है। NOT EXISTSहमेशा पंक्ति वापस आ जाएगी लेकिन NOT INयदि उप क्वेरी कोई भी पंक्ति रिटर्न केवल ऐसा ही करेगा।
मार्टिन स्मिथ

5

यदि डेटाबेस क्वेरी को अनुकूलित करने में अच्छा है, तो दो पहले तीसरे के करीब कुछ में बदल जाएंगे।

आपके जैसे सरल स्थितियों के लिए आप सवाल करते हैं, इसमें बहुत कम या कोई अंतर नहीं होना चाहिए, क्योंकि इन सभी को जोड़ के रूप में निष्पादित किया जाएगा। अधिक जटिल प्रश्नों में, डेटाबेस आउट not inएंड not existsक्वेरी से जुड़ने में सक्षम नहीं हो सकता है । उस स्थिति में क्वेरीज़ बहुत धीमी हो जाएंगी। दूसरी ओर, एक जॉइन भी बुरी तरह से प्रदर्शन कर सकता है यदि कोई इंडेक्स नहीं है जिसका उपयोग किया जा सकता है, इसलिए सिर्फ इसलिए कि आप एक जॉइन का उपयोग करते हैं इसका मतलब यह नहीं है कि आप सुरक्षित हैं। आपको यह बताने के लिए क्वेरी की निष्पादन योजना की जांच करनी होगी कि क्या कोई प्रदर्शन समस्याएँ हो सकती हैं।


2

यह मानते हुए कि आप अशक्तताओं से बच रहे हैं, वे सभी मानक SQL का उपयोग करके एंटी-जॉइन लिखने के तरीके हैं ।

एक स्पष्ट चूक का उपयोग करने के बराबर है EXCEPT:

SELECT a FROM table1
EXCEPT
SELECT a FROM table2

ओरेकल में नोट आपको MINUSऑपरेटर का उपयोग करने की आवश्यकता है (यकीनन एक बेहतर नाम):

SELECT a FROM table1
MINUS
SELECT a FROM table2

मालिकाना सिंटैक्स की बात करें, तो गैर-मानक समकक्ष भी हो सकते हैं जो आपके द्वारा उपयोग किए जा रहे उत्पाद के आधार पर उदाहरण OUTER APPLYके लिए SQL Server (जैसे कुछ) में हो:

SELECT t1.a
  FROM table1 t1
       OUTER APPLY 
       (
        SELECT t2.a
          FROM table2 t2
         WHERE t2.a = t1.a
       ) AS dt1
 WHERE dt1.a IS NULL;

0

जब बहु-क्षेत्र प्राथमिक कुंजी के साथ तालिका में डेटा सम्मिलित करने की आवश्यकता होती है, तो विचार करें कि यह बहुत तेज़ होगा (मैंने एक्सेस में प्रयास किया लेकिन मुझे लगता है कि किसी डेटाबेस में) यह जांचने के लिए नहीं कि "तालिका में 'ऐसे' मानों के साथ रिकॉर्ड मौजूद नहीं है" - बल्कि केवल टेबल में डालें, और अतिरिक्त रिकॉर्ड (कुंजी द्वारा) दो बार नहीं डाले जाएंगे।


0

प्रदर्शन परिप्रेक्ष्य हमेशा उल्टे कीवर्ड का उपयोग करने से बचें, जैसे कि NOT, NOT EXISTS, ... क्योंकि उलटा आइटम की जांच करने के लिए DBMS को सभी उपलब्ध के माध्यम से चलाने और उलटा चयन को छोड़ने की आवश्यकता होती है।


1
और क्या तुम प्रस्ताव के रूप में प्रस्ताव जब आप वास्तव में जरूरत है NOT?
अगस्त

खैर जब कारण का कोई विकल्प नहीं होता है तो हमें ऑपरेशन और नॉट का उपयोग करने की आवश्यकता होती है, इसलिए वे मौजूद हैं। जब हमारे पास कोई अन्य वैकल्पिक समाधान होता है, तो सबसे अच्छा व्यवहार यह होता है।
लहिरू कोरे

@onedaywhen, यदि कोई ऑप्टिमाइज़र एक क्वेरी को बदल देता है और यह गलत परिणाम देता है तो यह एक बग है
डेविड דוitzו Markovitz

@DuduMarkovitz: हाँ और यदि आप SQL सर्वर टीम से संपर्क करते हैं और वे बग को स्वीकार करते हैं लेकिन इसे ठीक करने से इंकार करते हैं क्योंकि वे कहते हैं कि ऐसा करने से क्वेरीज़ धीमी हो सकती हैं, तो यह एक बग है जिससे आपको निपटना होगा
onedaywhen

@onedaywhen - यह एक काल्पनिक परिदृश्य नहीं था जिसे मैं मानती हूं :-) क्या आप किसी भी तरह बग विवरणों को याद करते हैं?
डेविड 16ו Davidו मार्कोविट्ज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.