2008-10-22 14 views
22

मेरे पास दो टेबल संस्थान और परिणाम हैं और मैं देखना चाहता हूं कि संस्थानों के लिए कोई परिणाम हैं या नहीं, जिससे मैं उन परिणामों को बाहर कर सकता हूं जिनके परिणाम नहीं हैं।क्या मुझे जॉइन या EXISTS का उपयोग करके बेहतर प्रदर्शन मिल सकता है?

क्या मुझे जॉइन या EXISTS का उपयोग करके बेहतर प्रदर्शन मिल सकता है?

धन्यवाद,
-Nimesh

+0

यह वास्तविक सवाल नहीं है क्योंकि यह बेहद सामान्य है। उन्हें कम से कम थोड़ा और संदर्भ निर्दिष्ट करने की आवश्यकता है। –

+0

मैंने प्रश्न की अत्यंत सामान्य प्रकृति के कारण व्यक्तिपरक टैग जोड़ा। –

+0

@ निमेश - इस विशेष मामले में, विवरण आपके मित्र हैं। जितना अधिक विवरण आप एक उपयोगी, रचनात्मक उत्तर प्राप्त करने की अधिक संभावना प्रदान कर सकते हैं। एसक्यूएल का कौन सा स्वाद (i। ई। ओरेकल या एमएस एसक्यूएल सर्वर)? आप जिन टेबलों से पूछ रहे हैं उनकी संरचना क्या है? आदि इत्यादि। –

उत्तर

0

वे पूरी तरह से अलग बातें करते हैं। आप क्या हासिल करने का प्रयास कर रहे हैं? यह उचित क्वेरी संरचना का सबसे अच्छा निर्धारण करेगा।

+1

कोई जवाब नहीं .. –

0

यदि आप बाएं (या दाएं) बाहरी जुड़ने या अस्तित्व में मौजूद सबकुरी का उपयोग करने का जिक्र कर रहे हैं, तो मुझे काफी यकीन है कि बाएं बाहरी शामिल प्रदर्शन के अनुसार जीतता है। उदाहरण के लिए:

SELECT t1.* FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.id = t2.id WHERE t2.id IS NULL

ऊपर बराबर उप क्वेरी से जल्दी होना चाहिए, और यदि आप विशेष रूप से चर्चा करते हुए कर रहे हैं मौजूद है - अच्छी तरह से है, जहां संरचना की अनुमति देता है, एक आंतरिक में शामिल होने हमेशा पसंदीदा विकल्प हो जाएगा।

14

यह निर्भर करता है।

आखिरकार 2 पूरी तरह से अलग-अलग उद्देश्यों को पूरा करते हैं।

आप संबंधित रिकॉर्ड तक पहुंचने के लिए 2 टेबल में शामिल हों। यदि आपको संबंधित रिकॉर्ड में डेटा तक पहुंचने की आवश्यकता नहीं है तो आपको उनसे जुड़ने की आवश्यकता नहीं है।

EXISTS का उपयोग यह निर्धारित करने के लिए किया जा सकता है कि किसी दिए गए डेटासेट में टोकन मौजूद है या नहीं, लेकिन आप संबंधित रिकॉर्ड तक पहुंचने की अनुमति नहीं देंगे।

आपके मन में 2 विधियों का एक उदाहरण पोस्ट करें और मैं आपको एक बेहतर विचार देने में सक्षम हूं।


अपने दो तालिकाओं संस्थानों और परिणाम के साथ अगर आप संस्थाओं है कि परिणामों की एक सूची चाहते हैं, इस प्रश्न के लिए सबसे कारगर होगा:

select Institutions.institution_name 
from Institutions 
inner join Results on (Institutions.institution_id = Results.institution_id) 

आप एक institution_id है और सिर्फ अगर जानना चाहते हैं यह परिणाम है, का उपयोग कर मौजूद है तेजी से हो सकता है:

if exists(select 1 from Results where institution_id = 2) 
    print "institution_id 2 has results" 
else 
    print "institution_id 2 does not have results" 
+0

इच्छा है कि मैं सिर्फ आपके लिए अपनी पोस्ट संपादित कर सकता हूं .... सर्वर? ;-) –

+0

चूंकि आपकी स्पष्टीकरण ठीक है, "तेज हो सकती है" प्रश्न का एक छोटा सा जवाब है जो विकल्पों में से एक तेज़ है। – Magier

3

मैं कहना चाहता हूँ एक में शामिल हों धीमी है, कुछ पाता है क्योंकि आपकी क्वेरी निष्पादन बंद हो जाता है के रूप में जल्द ही एक कॉल मौजूद है, जबकि एक में शामिल हों cont होगा बहुत अंत तक inu।

संपादित करें: लेकिन यह क्वेरी पर निर्भर करता है। यह ऐसा कुछ है जिसे केस-दर-मामले आधार पर तय किया जाना चाहिए।

+0

अपने मामले में वह डेटा की अनुपस्थिति की तलाश में है, इसलिए उसे अभी भी संपूर्ण परिणाम तालिका (या, उम्मीद है, सूचकांक) –

+0

सही स्कैन करने की आवश्यकता होगी। मैंने इसे स्पष्ट करने से पहले पोस्ट किया .. मैं इस जवाब को भी हटा सकता हूं .. मुझे यकीन नहीं है कि मुझे चाहिए। :) – Kon

1

क्या आप एक सहसंबंधित सबक्वायरी के हिस्से के रूप में EXISTS का उपयोग कर रहे हैं? यदि हां, तो शामिल होना लगभग हमेशा तेज होगा।

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

4

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

0

आप संस्थाओं है कि परिणाम नहीं था चाहते हैं, तो एक 'नहीं कहाँ मौजूद है' सबक्वेरी तेज, हो के रूप में यह उन है कि परिणामों के लिए एक एकल परिणाम पाता है के रूप में यह रूप में जल्द ही बंद हो जाएगा होगा ...

यदि आप संस्थानों को परिणाम के साथ चाहते हैं, लेकिन आप वास्तव में परिणाम नहीं चाहते हैं, वही बात। 'जहां मौजूद है' सबक्वायरी का उपयोग करें .. जैसे ही इसे एक परिणाम मिल जाएगा, यह बंद हो जाएगा ... यह भी सुनिश्चित करता है कि परिणाम सेट में प्रति संस्थान केवल एक रिकॉर्ड होगा, जबकि यदि आपके पास एकाधिक परिणामों के साथ एक संस्थान था, तो दृष्टिकोण में शामिल होने की आवश्यकता होगी कि आप डुप्लिकेट कार्टेशियन उत्पाद पंक्तियों को खत्म करने के लिए 'विशिष्ट' कीवर्ड या 'ग्रुप बाय' क्लॉज जोड़ दें जो एक ही इंस्टीट्यूशन से मेल खाने वाले एकाधिक परिणाम रिकॉर्ड से प्रोडक्ट किया जाएगा।

यदि आपको परिणामों की आवश्यकता है, तो जॉइन करें - एक इनर जॉइन करें यदि आप परिणामों के बिना इन्सिट्यूशन देखना नहीं चाहते हैं, और यदि आप सभी संस्थानों को देखना चाहते हैं, तो कोई बाहरी शामिल नहीं है, जिनमें कोई परिणाम नहीं है।

5

यह आपके अनुकूलक पर निर्भर करता है। मैंने ओरेकल 10 जी और 11 जी में नीचे दिए गए दो की कोशिश की। 10 जी में, दूसरा थोड़ा तेज था। 11 जी में, वे समान थे।

हालांकि, # 1 वास्तव में EXISTS खंड का दुरुपयोग है। मिलान खोजने के लिए जुड़ें का उपयोग करें।

select * 
from 
    table_one t1 
where exists (
      select * 
      from table_two t2 
      where t2.id_field = t1.id_field 
      ) 
order by t1.id_field desc 


select t1.* 
from 
    table_one t1 
,table_two t2 
where t1.id_field = t2.id_field 
order by t1.id_field desc 
+0

शायद पहले विकल्प में उप-क्वेरी केवल * के बजाय t2.id_field लौटाता है, यह समय को क्षतिपूर्ति कर सकता है। कभी-कभी वापसी का आकार प्रदर्शन को भी प्रभावित करता है। विशेष रूप से इस मामले में यह थोड़ा अलग है। शुभकामनाएं और धन्यवाद !!! – tanovellino

15

कथन, आंकड़े और डीबी सर्वर के आधार पर इससे कोई फर्क नहीं पड़ता - वही अनुकूलित क्वेरी योजना तैयार की जा सकती है। - एक मेज के लिए दूसरे से काफी बड़ा

  • नेस्टेड लूप:

    वहाँ मूलतः 3 तरीके कि डीबीएस हुड के नीचे टेबल में शामिल होने हैं। छोटी तालिका में प्रत्येक पंक्ति को बड़ी संख्या में प्रत्येक पंक्ति के लिए चेक किया जाता है।

  • विलय - एक ही क्रम क्रम में दो तालिकाओं के लिए। दोनों क्रम में चलाए जाते हैं और मेल खाते हैं जहां वे मेल खाते हैं।

  • हैश - बाकी सब कुछ। अस्थायी तालिकाओं का उपयोग मैचों के निर्माण के लिए किया जाता है।

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

मैं कहूंगा कि आपको SQL कथन दोनों लिखने और क्वेरी योजनाओं की तुलना करने की आवश्यकता है। आप पाते हैं कि आपके पास कौन सा डेटा है, इस पर निर्भर करता है कि वे काफी कुछ बदलते हैं।

उदाहरण के लिए यदि [संस्थान] और [परिणाम] समान आकार हैं और दोनों इंस्टीट्यूशन आईडी पर क्लस्टर किए गए हैं तो एक विलय में शामिल होना सबसे तेज़ होगा। यदि [परिणाम] [संस्थान] से काफी बड़ा है तो एक नेस्टेड लूप तेज हो सकता है।

1

दरअसल, समस्या के अपने अस्पष्ट वर्णन से, यह मेरे लिए एक नहीं जैसी क्वेरी में लगता है सबसे स्पष्ट यह कोड करने के लिए जिस तरह से किया जाता है:

SELECT * 
    FROM Institutions 
    WHERE InstitutionID NOT IN (
    SELECT DISTINCT InstitutionID 
     FROM Results 
    ) 
+0

क्यों दुनिया में आप एक विशिष्ट जोड़ देंगे? या तो नंबर 1 इस सूची में है (1, 1, 1, 2, 2, 5, 5, 7) या यह नहीं है। सूची को सॉर्ट और फ़िल्टर करने के लिए यह पूरी तरह से महत्वहीन है। वास्तव में, जब मैं इसे 10.2.0.3 में करता हूं, तो इसे पूरी तरह नजरअंदाज कर दिया जाता है। –

+0

निष्पादन योजनाओं को देखते हुए मेरे अनुभव में, ओरेकल इसे अद्वितीय मानों पर फ़िल्टर करेगा चाहे आपके पास DISTINCT कीवर्ड हो या नहीं। इसलिए मैं इसे शामिल करना पसंद करता हूं क्योंकि यह कोड स्पष्ट करने का उद्देश्य बनाता है। –

1

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

** इस विधि से परिचित नहीं उन लोगों के लिए:

SELECT 
    MyTable.MyTableID 
FROM 
    dbo.MyTable T1 
LEFT OUTER JOIN dbo.MyOtherTable T2 ON 
    T2.MyTableID = T1.MyTableID 
WHERE 
    T2.MyOtherTableID IS NULL 

SELECT 
    MyTable.MyTableID 
FROM 
    dbo.MyTable T1 
WHERE NOT EXISTS (SELECT * FROM MyOtherTable T2 WHERE T2.MyTableID = T1.MyTableID) 

के बराबर है कि MyOtherTableID संभालने एक नहीं NULL स्तंभ है। हालांकि पहली विधि आमतौर पर EXISTS विधि से तेज़ी से प्रदर्शन नहीं करती है।

+0

http://dba.stackexchange.com/a/4010/630 + बाद के लिंक देखें। बाएं जॉइन को एक डिस्टिंट की आवश्यकता हो सकती है जो आपको भी बोलेक्स करेगा। * आम तौर पर * EXISTS तेज और अर्थात् सही है – gbn

1

यदि परिणाम तालिका में INSTITUTION प्रति एक से अधिक पंक्तियां हैं, EXISTS() में अतिरिक्त संस्थानों का चयन करने की आवश्यकता नहीं है, तो अतिरिक्त लाभ है।

प्रदर्शन के लिए, मैंने joins, IN(), and EXISTS() प्रत्येक प्रकार के उपयोग में सबसे तेज़ देखा है। अपने उद्देश्यों के लिए सबसे अच्छी विधि खोजने के लिए आपको परीक्षण करना होगा।

1

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

+1

stackoverflow में आपका स्वागत है। यह सवाल काफी पुराना है और अच्छी तरह से कवर किया गया था। ऐसे पुराने धागे को पुनर्जीवित करने से पहले, कृपया सुनिश्चित करें कि आपकी प्रतिक्रिया वार्तालाप में कुछ महत्वपूर्ण जोड़ती है, – Leigh

संबंधित मुद्दे