SQL ज्वाइन Vs SQL सबक्वेरीज़ (प्रदर्शन)?


110

मैं जानना चाहता हूं कि क्या मेरे पास कुछ इस तरह से शामिल होने का सवाल है -

Select E.Id,E.Name from Employee E join Dept D on E.DeptId=D.Id

और एक उपश्रेणी कुछ इस तरह से -

Select E.Id,E.Name from Employee Where DeptId in (Select Id from Dept)

जब मैं प्रदर्शन पर विचार करता हूं कि दोनों में से कौन सा प्रश्न तेज होगा और क्यों ?

क्या ऐसा भी समय है जब मुझे एक के बाद एक को पसंद करना चाहिए?

क्षमा करें यदि यह बहुत तुच्छ है और पहले पूछा गया था लेकिन मैं इसके बारे में भ्रमित हूं। इसके अलावा, यह बहुत अच्छा होगा यदि आप लोग मुझे ऐसे उपकरण सुझा सकते हैं जिनका उपयोग मुझे दो प्रश्नों के प्रदर्शन को मापने के लिए करना चाहिए। आपका बहुत बहुत धन्यवाद!


5
@ ल्यूकोरो, इस सवाल को sql-server-2008 टैग किया गया है, जहां आपके द्वारा उल्लिखित पोस्ट को MySql टैग किया गया है। आप अनुमान लगा सकते हैं कि उत्तर समान होंगे। प्रदर्शन अनुकूलन दो RDBMS पर अलग तरीके से किया जाता है।
फ्रेंकोइस बोथा

जवाबों:


48

मैं पहली क्वेरी को शीघ्रता से पेश करूंगा, इसका मुख्य कारण यह है कि आपके पास एक समतुल्यता और एक स्पष्ट JOIN है। मेरे अनुभव INमें एक बहुत धीमा ऑपरेटर है, क्योंकि एसक्यूएल सामान्य रूप WHEREसे "या" ( WHERE x=Y OR x=Z OR...) द्वारा अलग किए गए खंडों की एक श्रृंखला के रूप में इसका मूल्यांकन करता है ।

यद्यपि सभी थिंग्स SQL ​​के साथ, आपका माइलेज भिन्न हो सकता है। गति अनुक्रमणिका पर बहुत अधिक निर्भर करेगी (क्या आपके पास दोनों आईडी स्तंभों पर अनुक्रमित हैं? यह अन्य चीजों के बीच बहुत मदद करेगा ...)।

100% निश्चितता के साथ बताने के लिए एकमात्र वास्तविक तरीका जो प्रदर्शन ट्रैकिंग को चालू करना है (IO सांख्यिकी विशेष रूप से उपयोगी है) और दोनों को चलाएं। रन के बीच अपना कैश साफ़ करना सुनिश्चित करें!


16
मुझे इस उत्तर पर गंभीर संदेह है, क्योंकि अधिकांश DBMS, निश्चित रूप से SQL Server 2008 और बाद में, एकल आईडी सबक्वेरी (सहसंबद्ध नहीं है, जिसका अर्थ है: एकाधिक बाहरी क्वेरी कॉलम का उल्लेख नहीं करना) को अपेक्षाकृत तेज़ अर्ध-सम्मिलित करना। इसके अलावा, जैसा कि पहले एक अन्य जवाब में उल्लेख किया गया था, पहला, असली जुड़ाव विभाग को मिलान आईडी में होने वाली प्रत्येक घटना के लिए एक पंक्ति लौटाएगा - यह एक अद्वितीय आईडी के लिए कोई फर्क नहीं पड़ता है, लेकिन आपको कहीं और डुप्लिकेट का टन देगा। DISTINCT या GROUP BY के साथ इन्हें छाँटना एक और भारी प्रदर्शन भार होगा। SQL सर्वर प्रबंधन स्टूडियो में निष्पादन योजनाओं की जांच करें!
एरिक हार्ट

2
OR के समतुल्य IN खंड पैरामीटर / मान सूचियों पर लागू होता है, लेकिन उपश्रेणियों के लिए नहीं, जिन्हें ज्यादातर जोड़ की तरह माना जाता है।
एरिक हार्ट

42

खैर, मेरा मानना ​​है कि यह एक "पुराना लेकिन सोना" सवाल है। उत्तर है, यह निर्भर करता है!"। प्रदर्शन इतने नाजुक विषय हैं कि यह कहना बहुत मूर्खतापूर्ण होगा: "कभी भी उप-वर्गों का उपयोग न करें, हमेशा जुड़ें"। निम्नलिखित लिंक में, आपको कुछ बुनियादी सर्वोत्तम अभ्यास मिलेंगे जो मुझे बहुत मददगार लगे हैं:

मेरे पास 50000 तत्वों के साथ एक तालिका है, जिसका परिणाम मुझे 739 तत्वों की तलाश में था।

मेरी क्वेरी पहले थी:

SELECT  p.id,
    p.fixedId,
    p.azienda_id,
    p.categoria_id,
    p.linea,
    p.tipo,
    p.nome
FROM prodotto p
WHERE p.azienda_id = 2699 AND p.anno = (
    SELECT MAX(p2.anno) 
    FROM prodotto p2 
    WHERE p2.fixedId = p.fixedId 
)

और इसे क्रियान्वित करने में 7.9 का समय लगा।

मेरा प्रश्न इस पर अंतिम है:

SELECT  p.id,
    p.fixedId,
    p.azienda_id,
    p.categoria_id,
    p.linea,
    p.tipo,
    p.nome
FROM prodotto p
WHERE p.azienda_id = 2699 AND (p.fixedId, p.anno) IN
(
    SELECT p2.fixedId, MAX(p2.anno)
    FROM prodotto p2
    WHERE p.azienda_id = p2.azienda_id
    GROUP BY p2.fixedId
)

और इसमें 0.0256 का समय लगा

अच्छा SQL, अच्छा है।


3
दिलचस्प है, क्या आप बता सकते हैं कि ग्रुप बाय को कैसे जोड़ा जाए?
cozos

6
उपकुंजी द्वारा उत्पन्न अस्थायी तालिका छोटी थी। इसलिए निष्पादन जल्दी होता है क्योंकि जाँच करने के लिए कम डेटा होते हैं।
निर्बल

2
मुझे लगता है कि पहली क्वेरी में आपने बाहरी क्वेरी और सबक्वेरी के बीच वैरिएबल साझा किया है, इसलिए मुख्य क्वेरी में प्रत्येक पंक्ति के लिए, सबक्वेरी निष्पादित होती है, लेकिन दूसरे में सबक्वेरी केवल एक बार निष्पादित करता है और इस तरह से प्रदर्शन में सुधार हुआ है।
अली फरदजपुर

1
Sql सर्वर और MySql और ... Sql (NoSql को छोड़कर) बुनियादी ढांचे में समान हैं। हमारे पास एक प्रकार का क्वेरी ऑप्टिमाइज़ेशन इंजन है, जो कि IN (...) क्लॉज़ को जुड़ने के लिए परिवर्तित करता है (यदि यह संभव था)। लेकिन जब आपके पास एक अच्छी तरह से अनुक्रमित कॉलम (इसकी कार्डिनैलिटी के आधार पर) पर एक समूह होता है तो यह बहुत तेज होगा। तो यह वास्तव में स्थिति पर निर्भर करता है।
एलिक्स

10

SQl सर्वर उन्हें कैसे व्याख्या करेगा में अंतर को देखने के लिए निष्पादन योजनाओं को देखना शुरू करें। आप वास्तव में कई बार प्रश्नों को चलाने के लिए और विभेदक प्राप्त करने के लिए Profiler का उपयोग कर सकते हैं।

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

EXISTS अक्सर इन दोनों में से बेहतर होता है और जब आप बायाँ जॉइन कर रहे होते हैं, जहाँ आप सभी रिकॉर्ड्स को लेफ्ट जॉइन टेबल में नहीं रखना चाहते हैं, तो EXISTS अक्सर बहुत बेहतर विकल्प होता है।


9

प्रदर्शन उस डेटा की मात्रा पर आधारित होता है, जिसे आप निष्पादित कर रहे हैं ...

यदि यह 20k के आसपास कम डेटा है। जोइन बेहतर काम करता है।

यदि डेटा 100k + की तरह अधिक है, तो IN बेहतर काम करता है।

यदि आपको अन्य तालिका से डेटा की आवश्यकता नहीं है, तो IN अच्छा है, लेकिन EXISTS के लिए जाना बेहतर है।

इन सभी कसौटियों का मैंने परीक्षण किया और तालिकाओं का उचित सूचकांक है।


4

प्रदर्शन समान होना चाहिए; सही तालिकाओं और क्लस्टरिंग को अपनी तालिकाओं पर लागू करना बहुत अधिक महत्वपूर्ण है ( उस विषय पर कुछ अच्छे संसाधन मौजूद हैं)।

(अद्यतन प्रश्न को प्रतिबिंबित करने के लिए संपादित)


4

हो सकता है कि दो प्रश्न शब्दार्थ के समतुल्य न हों। यदि कोई कर्मचारी एक से अधिक विभाग के लिए काम करता है (संभव है कि मैं जिस उद्यम के लिए काम करता हूं, तो, यह माना जाता है कि यह आपकी तालिका पूरी तरह से सामान्यीकृत नहीं है) तो पहली क्वेरी डुप्लिकेट पंक्तियों को लौटाएगी जबकि दूसरी क्वेरी नहीं होगी। इस मामले में प्रश्नों को समतुल्य बनाने के लिए, DISTINCTकीवर्ड को SELECTक्लॉज में जोड़ना होगा , जो प्रदर्शन पर प्रभाव डाल सकता है।

ध्यान दें कि अंगूठे का एक डिज़ाइन नियम है जिसमें कहा गया है कि एक तालिका में एक इकाई / वर्ग या संस्थाओं / वर्गों के बीच संबंध होना चाहिए, लेकिन दोनों नहीं। इसलिए, मेरा सुझाव है कि आप OrgChartकर्मचारियों और विभागों के बीच संबंध बनाने के लिए एक तीसरी तालिका बनाएं ।


4

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मुझे लगता है कि यह एक बहुत ही महत्वपूर्ण विषय है, खासकर आजकल जहां हमारे पास 10M + रिकॉर्ड हैं और डेटा के टेराबाइट्स के बारे में बात करते हैं।

मैं निम्नलिखित टिप्पणियों के साथ वजन भी करूंगा। मेरी तालिका ([डेटा]) में लगभग 45M रिकॉर्ड हैं, और मेरी [बिल्लियों] तालिका में लगभग 300 रिकॉर्ड हैं। मैं उन सभी प्रश्नों के लिए व्यापक अनुक्रमण कर रहा हूं जिनके बारे में मैं बात करने वाला हूं।

उदाहरण 1 पर विचार करें:

UPDATE d set category = c.categoryname
FROM [data] d
JOIN [cats] c on c.id = d.catid

बनाम उदाहरण 2:

UPDATE d set category = (SELECT TOP(1) c.categoryname FROM [cats] c where c.id = d.catid)
FROM [data] d

उदाहरण 1 को चलाने में लगभग 23 मिनट लगे। उदाहरण 2 में लगभग 5 मिनट लगे।

इसलिए मैं यह निष्कर्ष निकालूंगा कि इस मामले में उप-प्रश्न बहुत तेज है। बेशक यह ध्यान रखें कि मैं M.2 SSD ड्राइव का उपयोग कर रहा हूँ जो i / o @ 1GB / sec (thats बाइट्स बिट्स नहीं) में सक्षम है, इसलिए मेरे अनुक्रमित वास्तव में बहुत तेज़ हैं। तो यह आपकी परिस्थिति में गति को भी प्रभावित कर सकता है

यदि इसका एक-बंद डेटा क्लींजिंग है, तो संभवतः इसे चलाने और खत्म करने के लिए सबसे अच्छा है। मैं TOP (10000) का उपयोग करता हूं और देखता हूं कि बड़ी क्वेरी को हिट करने से पहले कितने समय लगते हैं और रिकॉर्ड की संख्या से गुणा करें।

यदि आप उत्पादन डेटाबेस का अनुकूलन कर रहे हैं, तो मैं दृढ़ता से पूर्व-प्रसंस्करण डेटा का सुझाव दूंगा, अर्थात ट्रिगर्स या जॉब-ब्रोकर को एएसक्यूएन अपडेट रिकॉर्ड्स का उपयोग करना, ताकि वास्तविक समय तक पहुंच स्थिर डेटा को पुनः प्राप्त कर सके।


0

आप वस्तुनिष्ठ उत्तर पाने के लिए व्याख्या योजना का उपयोग कर सकते हैं।

आपकी समस्या के लिए, एक एक्ज़िस्ट फ़िल्टर शायद सबसे तेज़ प्रदर्शन करेगा।


2
"एक्ज़िस्ट्स फ़िल्टर शायद सबसे तेज़ प्रदर्शन करेगा" - शायद नहीं, मुझे लगता है, हालांकि एक निश्चित उत्तर के लिए वास्तविक डेटा के खिलाफ परीक्षण की आवश्यकता होगी। एक्ज़िस्ट फ़िल्टर तेजी से होने की संभावना है, जहाँ एक ही लुकअप मान के साथ कई पंक्तियाँ हैं - इसलिए मौजूद फ़िल्टर तेज़ी से चल सकता है यदि क्वेरी जाँच रही है कि क्या अन्य कर्मचारियों को उसी विभाग से रिकॉर्ड किया गया था, लेकिन संभवत: जब कोई विभाग के खिलाफ देख रहा हो तालिका।

क्या यह उस अंतिम परिदृश्य में धीमी गति से चलेगा?
स्नेक

यह ऑप्टिमाइज़र पर निर्भर करेगा - कुछ परिस्थितियों में, यह हो सकता है, लेकिन आम तौर पर मैं बहुत समान प्रदर्शन की उम्मीद करूंगा।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.