SQL सर्वर बनाम EXISTS प्रदर्शन


115

मैं उत्सुक हूं कि निम्नलिखित में से कौन अधिक कुशल होगा?

मैं हमेशा उपयोग करने के बारे में थोड़ा सतर्क INरहा हूं क्योंकि मेरा मानना ​​है कि SQL सर्वर परिणाम को एक बड़े IFबयान में बदल देता है । एक बड़े परिणाम सेट के लिए, यह खराब प्रदर्शन के कारण हो सकता है। छोटे परिणाम सेट के लिए, मुझे यकीन नहीं है कि या तो बेहतर है। बड़े परिणाम सेट के लिए, EXISTSअधिक कुशल नहीं होगा ?

WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

बनाम

WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])

8
इसका पता लगाने का सबसे अच्छा तरीका यह है कि आप इसे आज़माएँ और कुछ खसरा काम करें।
क्लॉस बिसकोव पेडर्सन

10
वहाँ इस के लिए एक gazillion डुप्लिकेट हो गया है ......
marc_s

5
@marc_s - शायद, लेकिन उस समय में मुझे इस विषय पर सभी पोस्ट देखने के लिए ले जाया गया था, और जो मेरे मामले में फिट बैठता है उसे पाएं, मेरे पास मेरे प्रश्न के चार उत्तर थे।
रैंडी मिंडर

7
आप चाहते हैं कर रहे हैं FYI करें, तो सबसे performant तरह से, आप कर सकते हैं select 1 from Base...अपने में where existsजब से तुम वास्तव में परिणाम के बारे में परवाह नहीं है, एक पंक्ति वास्तव में मौजूद है सिर्फ इतना है कि।
ब्रैड

2
@marc_s जो वास्तव में दुखी है, क्योंकि मैंने पदों के माध्यम से देखने के लिए समय निकाला ताकि स्टैकओवरफ्लो में कोई और कचरा न जोड़ा जा सके। मुझे अपना काम पूरा करने के लिए एक अनुरूप जवाब की आवश्यकता नहीं है। इस तरह की सोच ने कुछ ही जवाबों के साथ कुछ के स्थान पर एक
गज़िल

जवाबों:


140

EXISTS तेजी से होगा क्योंकि एक बार इंजन हिट हो जाने के बाद, यह देखना छोड़ देगा क्योंकि स्थिति सही साबित हुई है।

इसके साथ IN, यह आगे की प्रक्रिया से पहले उप-क्वेरी से सभी परिणाम एकत्र करेगा।


4
ये एक अच्छा बिंदु है। IN स्टेटमेंट के लिए SQL सर्वर को एक पूरा परिणाम सेट जनरेट करने की आवश्यकता होती है, और फिर एक बड़ा IF स्टेटमेंट बनाता है जो मुझे लगता है।
रैंडी मिंदर

72
यह सच हुआ करता था, लेकिन वर्तमान संस्करणों में (कम से कम 2008) ऑप्टिमाइज़र बहुत चालाक होता है ... यह वास्तव में IN () को एक EXISTS () की तरह मानता है।
आरोन बर्ट्रेंड

11
@ एरॉन - हाँ, आमतौर पर ऑप्टिमाइज़र आंतरिक रूप से एक बेहतर योजना का उत्पादन करेगा। हालाँकि, आंतरिक शॉर्टकट्स पर निर्भर होना अधिक जटिल परिदृश्यों में हानिकारक हो सकता है।
स्कॉट कोट

2
यह सिर्फ गलत है। यह 2010 में था और अब भी है।
मैग्नस

2
IN और EXISTS में एक ही क्वेरी प्लान और IO है। यह सोचने का कोई कारण नहीं है कि वे प्रदर्शन में भिन्न हैं। अपने समय के आँकड़ों की जाँच करें और खुद को संकलित करें
नेल्सन

40

स्वीकृत उत्तर संक्षिप्त है और इसमें प्रश्न थोड़ा ढीला है:

1) न तो स्पष्ट रूप से उल्लेख किया गया है कि क्या एक आवरण सूचकांक बाएं, दाएं या दोनों पक्षों में मौजूद है।

2) न तो इनपुट लेफ्ट साइड सेट और इनपुट राइट साइड सेट का आकार लेता है।
(सवाल में एक समग्र बड़े परिणाम सेट का उल्लेख है )।

मेरा मानना ​​है कि ऑप्टिमाइज़र "बनाम" मौजूद "के बीच कनवर्ट करने के लिए पर्याप्त स्मार्ट है जब (1) और (2) के कारण महत्वपूर्ण लागत अंतर होता है, अन्यथा यह केवल संकेत के रूप में उपयोग किया जा सकता है (उदाहरण के लिए आगे के उपयोग को प्रोत्साहित करने के लिए मौजूद है] दायीं ओर एक खोजी सूचकांक)।

दोनों रूपों को आंतरिक रूप से जुड़ने के लिए रूपांतरित किया जा सकता है, जुड़ने का क्रम उलटा है, और लूप, हैश या मर्ज के रूप में चलाया जा सकता है - अनुमानित पंक्ति गणना (बाएं और दाएं) और बाएं, दाएं या दोनों पक्षों में सूचकांक अस्तित्व के आधार पर।


3
पता नहीं क्यों इस उत्कृष्ट उत्तर ने कोई और ध्यान नहीं दिया। दोनों पक्षों के लिए सूचकांक / संरचना को समझना मैं सहमत हो सकता है। ख़ूब कहा है।
शेल्डन 20

आशावादी हमेशा ही INऔर के लिए एक ही योजना देता है EXISTS। कोशिश करें और किसी भी मामले के साथ आएं, जहां उन्हें एक ही योजना नहीं मिलती है (हालांकि यह लागू नहीं होती है ) NOT INऔरNOT EXISTS
मार्टिन स्मिथ

@MartinSmith मुझे लगता है कि आप जानते हैं कि आप किस बारे में बात कर रहे हैं, लेकिन क्या आपके पास कोई सबूत है कि योजनाएं हमेशा एक ही हैं? यदि ऐसा है, तो यह यहां दशकों पुरानी असहमति को स्पष्ट करेगा।
MarredCheese

@MarredCheese - लोगों पर दावा है कि यह इसका एक उदाहरण प्रस्तुत करने के लिए अलग है
मार्टिन स्मिथ

37

मैंने SQL Server 2005 और 2008, और EXISTS और IN दोनों पर कुछ परीक्षण किए हैं, जो वास्तव में एक ही वास्तविक निष्पादन योजना के साथ आते हैं, जैसा कि अन्य ने कहा है। ऑप्टिमाइज़र इष्टतम है। :)

हालाँकि, इसके बारे में कुछ पता होना चाहिए, अगर आप अपनी क्वेरी को सही नहीं बताते हैं, तो EXISTS, IN, और JOIN कभी-कभी अलग परिणाम दे सकते हैं: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx


5

यहाँ बहुत सारे भ्रामक उत्तर दिए गए हैं, जिनमें उच्च उत्थान वाला भी शामिल है (हालाँकि मुझे विश्वास नहीं है कि उनके ऑप्स का मतलब नुकसान था)। संक्षिप्त उत्तर है: ये समान हैं।

(T-) SQL भाषा में कई कीवर्ड हैं, लेकिन अंत में, केवल एक चीज जो हार्डवेयर पर होती है, वह संचालन है जैसा कि निष्पादन क्वेरी योजना में देखा गया है।

रिलेशनल (मैथ्स थ्योरी) ऑपरेशन हम तब करते हैं जब हम आह्वान करते हैं [NOT] INऔर [NOT] EXISTSसेमी ज्वाइन (उपयोग करते समय एंटी-जॉइन NOT) करते हैं। यह एक संयोग नहीं है कि संबंधित sql- सर्वर संचालन का एक ही नाम है । ऐसा कोई ऑपरेशन नहीं है जो उल्लेख करता है INया EXISTSकहीं भी - केवल (विरोधी) अर्ध जुड़ता है। इस प्रकार, ऐसा कोई तरीका नहीं है कि तार्किक-समकक्ष INबनाम EXISTSपसंद प्रदर्शन को प्रभावित कर सकता है क्योंकि एक और एकमात्र तरीका है, (एंटी) अर्ध निष्पादन कार्रवाई में शामिल होते हैं, ताकि उनके परिणाम मिल सकें

एक उदाहरण:

प्रश्न 1 ( योजना )

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

प्रश्न 2 ( योजना )

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

क्या आपने इसका परीक्षण किया है? यदि हां, तो क्या आप अपने SQL और अपने परिणामों को साझा कर सकते हैं?
UnhandledExcepSean

कई बार इसका परीक्षण किया। मैं एक और परीक्षण मामला बना सकता हूं, और मैं करूंगा, लेकिन एक परीक्षण मामले का मतलब यह नहीं है कि ऑप्टिमाइज़र अलग-अलग आंकड़ों के साथ तालिकाओं पर सटीक एक ही योजना करेगा। यह किसी को यह सोचने के लिए प्रेरित कर सकता है कि उत्तर आंशिक है - लेकिन कई अर्धचालक संचालकों का कोई भी तथ्य नहीं है। हो सकता है कि मुझे कहीं सूची मिल जाए और उसे लिंक कर दूं।
15:50 पर जॉर्ज मेनोटिस

5

मैं EXISTS के साथ IN पर जाऊंगा, नीचे लिंक देखूंगा:

एसक्यूएल सर्वर: बनाम बनाम एक्सिस में शामिल हों - तार्किक अंतर

एक आम गलत धारणा है कि IN लौटे परिणामों के संदर्भ में EXISTS या JOIN के समान व्यवहार करता है। यह बिल्कुल सही नहीं है।

IN: रिटर्न सच अगर एक निर्धारित मूल्य से एक सबक्वेरी या किसी सूची में किसी भी मान से मेल खाता।

अस्तित्व: यदि एक सबक्वेरी में कोई पंक्तियाँ हों तो यह सही है।

ज्वाइन करें: जॉइनिंग कॉलम पर 2 रिजल्ट्स ज्वाइन करते हैं।

ब्लॉग क्रेडिट: https://stackoverflow.com/users/31345/mladen-prajdic


वाह, आपके ब्लॉग और स्पष्टीकरण के लिए धन्यवाद।
ईसाई मुलर

3

इन मामलों में निष्पादन योजनाएं आमतौर पर समान होती हैं, लेकिन जब तक आप यह नहीं देखते हैं कि अनुक्रमणिका के सभी अन्य पहलुओं में आशावादी कारक कैसे हैं, तो आप वास्तव में कभी नहीं जान पाएंगे।


3

तो, IN, EXISTS जैसा नहीं है और न ही यह एक ही निष्पादन योजना का उत्पादन करेगा।

आमतौर पर EXISTS का उपयोग सहसंबंधी उपशम में किया जाता है, इसका मतलब है कि आप अपनी बाहरी क्वेरी के साथ EXISTS आंतरिक क्वेरी को शामिल करेंगे। परिणाम उत्पन्न करने के लिए और कदम जोड़ेंगे क्योंकि आपको बाहरी क्वेरी जोड़ को हल करने की आवश्यकता होती है और आंतरिक क्वेरी जुड़ती है, फिर दोनों से जुड़ने के लिए उनके क्लॉसेस से मेल खाती है।

आमतौर पर IN का उपयोग बाहरी क्वेरी के साथ आंतरिक क्वेरी को सहसंबंधित किए बिना किया जाता है, और इसे केवल एक चरण में हल किया जा सकता है (सर्वोत्तम स्थिति में)।

इस पर विचार करो:

  1. यदि आप IN और आंतरिक क्वेरी परिणाम का उपयोग अलग-अलग मानों की लाखों पंक्तियों में करते हैं, तो संभवतः यह दिए गए EXISTS की तुलना में SLOWER प्रदर्शन करेगा कि EXISTS क्वेरी निष्पादन योग्य है (बाहरी क्वेरी से जुड़ने के लिए सही अनुक्रमित है)।

  2. यदि आप EXISTS का उपयोग करते हैं और आपकी बाहरी क्वेरी के साथ जुड़ना जटिल है (प्रदर्शन के लिए अधिक समय, कोई उपयुक्त अनुक्रमणिका नहीं है) तो यह क्वेरी को बाहरी तालिका में पंक्तियों की संख्या से धीमा कर देगा, कभी-कभी पूरा होने का अनुमानित समय दिनों में हो सकता है। यदि आपके दिए गए हार्डवेयर के लिए पंक्तियों की संख्या स्वीकार्य है, या डेटा की कार्डिनैलिटी सही है (उदाहरण के लिए एक बड़े डेटा सेट में कम DISTINCT मान) IN तो EXISTS से तेज प्रदर्शन कर सकता है।

  3. उपरोक्त सभी को तब ध्यान दिया जाएगा जब आपके पास प्रत्येक टेबल पर उचित मात्रा में पंक्तियाँ हों (निष्पक्ष रूप से मेरा मतलब है कि आपके सीपीयू प्रसंस्करण और / या कैशिंग के लिए रैम थ्रेसहोल्ड से अधिक है)।

तो ANSWER यह DEPENDS है। आप IN या EXISTS के अंदर एक जटिल क्वेरी लिख सकते हैं, लेकिन अंगूठे के एक नियम के रूप में, आपको IN को विभिन्न मूल्यों के सीमित सेट और EXISTS के साथ उपयोग करने का प्रयास करना चाहिए, जब आपके पास बहुत सारे भिन्न मानों के साथ बहुत सी पंक्तियाँ हों।

चाल को स्कैन करने के लिए पंक्तियों की संख्या को सीमित करना है।

सादर,

MarianoC


1

का अनुकूलन करने के लिए EXISTS, बहुत शाब्दिक हो; कुछ बस होना चाहिए, लेकिन आपको वास्तव में सहसंबद्ध उप-क्वेरी से लौटाए गए किसी भी डेटा की आवश्यकता नहीं है। आप सिर्फ बूलियन स्थिति का मूल्यांकन कर रहे हैं।

इसलिए:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

क्योंकि सह-संबद्ध उप-क्वेरी है RBAR, पहला परिणाम हिट स्थिति को सत्य बनाता है, और इसे आगे नहीं संसाधित किया जाता है।


मैं हमेशा LEFT JOIN + NULL कोडिंग का उपयोग करने में बेहद सतर्क रहूंगा, क्योंकि यदि आप अपने NULL हैंडलिंग में बहुत सावधानी नहीं रखते हैं तो मिस्ड या तिरछे परिणाम प्राप्त करना बहुत आसान है। मैंने बहुत कम ही ऐसी स्थिति पाई है जहाँ EXISTS या CTE (लापता डेटा के लिए दोहराव, या सिंथेटिक सम्मिलन खोजने के लिए), दोनों एक ही आवश्यकताओं को पूरा नहीं करते हैं और LEFT JOIN + NULL
जोश लुईस

3
EXISTS के साथ उपयोग किए जाने पर TOP 1 पूर्ण बहिर्मुखी (या घटना निरर्थक) होना चाहिए। EXISTS हमेशा किसी भी मैचिंग रो को ढूंढते हुए लौटता है
कार्ल कीनिंगर

मैंने अब तक इस दृष्टिकोण के साथ कोई प्रदर्शन लाभ नहीं देखा। कृपया निष्पादन योजना के कुछ स्क्रीनशॉट
DaFi4

-1

मेरे सिर के ऊपर से और सही होने की गारंटी नहीं: मेरा मानना ​​है कि इस मामले में दूसरा तेजी से होगा।

  1. पहले में, सहसंबद्ध उपकुंजी संभवतः प्रत्येक पंक्ति के लिए उपकुंजी चलाने का कारण बनेगी।
  2. दूसरे उदाहरण में, उप-वर्ग को केवल एक बार चलना चाहिए, क्योंकि सहसंबद्ध नहीं है।
  3. दूसरे उदाहरण में, INएक मैच मिलते ही विल-सर्किट।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.