क्या JOIN स्थिति और WHERE की स्थिति के बीच निष्पादन अंतर है?


17

क्या इन दो उदाहरण प्रश्नों के बीच एक प्रदर्शन अंतर है?

क्वेरी 1:

select count(*)
from   table1 a
join   table2 b
on     b.key_col=a.key_col
where  b.tag = 'Y'

क्वेरी 2;

select count(*)
from   table1 a
join   table2 b
on     b.key_col=a.key_col
   and b.tag = 'Y'

केवल अंतर नोटिस पूरक स्थिति की नियुक्ति है; पहला एक WHEREखंड का उपयोग करता है और दूसरा खंड के लिए शर्त जोड़ता है ON

जब मैं अपने Teradata सिस्टम पर इन प्रश्नों को चलाता हूं, तो स्पष्टीकरण योजनाएं समान होती हैं और JOIN चरण प्रत्येक मामले में अतिरिक्त स्थिति दिखाता है। हालांकि, MySQL के बारे में इस SO प्रश्न पर , एक उत्तर ने सुझाव दिया कि दूसरी शैली पसंद की जाती है क्योंकि WHEREप्रसंस्करण जोड़ के बनने के बाद होता है।

क्या इस तरह के प्रश्नों को कोड करते समय एक सामान्य नियम का पालन करना है? मुझे लगता है कि यह मंच पर निर्भर होना चाहिए क्योंकि यह स्पष्ट रूप से मेरे डेटाबेस पर कोई फर्क नहीं पड़ता है, लेकिन शायद यह सिर्फ टेराडाटा की एक विशेषता है। और अगर यह है मंच निर्भर है, मैं बहुत ज्यादा पसंद कुछ प्रलेखन संदर्भ पाने के लिए चाहते हैं; मैं वास्तव में नहीं जानता कि क्या देखना है।


9
यह प्लेटफॉर्म पर निर्भर है, क्योंकि यह निर्भर करता है कि आरडीबीएमएस ऑप्टिमाइज़र पार्सिंग और ऑप्टिमाइज़ेशन से कैसे निपटता है।
फिलो

8
और जुड़े हुए सवाल का जवाब कई डाउनवोट का हकदार है। यहां तक ​​कि MySQL के आदिम ऑप्टिमाइज़र को यह समझ में आ जाएगा कि ये सरल प्रश्न समतुल्य हैं और यह कि "सभी खंडों के होने के बाद WHERE क्लॉज का मूल्यांकन किया जाता है" केवल एक तार्किक स्तर पर सही है, वास्तविक निष्पादन में नहीं।
ypercube y

1
वास्तव में डुप्लिकेट नहीं; वह प्रश्न और उत्तर "निहित" बनाम "स्पष्ट" जॉय सिंटैक्स की तुलना कर रहे थे। मैं विशेष रूप से पूरक शामिल होने की स्थितियों के बारे में पूछ रहा हूं।
बेल्वेल्यूबेक

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

जवाबों:


14

अध्याय 9 (पार्सर और ऑप्टिमाइज़र) के अनुसार, साशा पाचेव द्वारा पुस्तक MySQL इंटरनल्स को समझना पुस्तक का पृष्ठ 172

MySQL आंतरिक को समझना

यहाँ निम्नलिखित कार्यों के रूप में एक क्वेरी का मूल्यांकन टूट रहा है:

  • निर्धारित करें कि तालिकाओं से रिकॉर्ड प्राप्त करने के लिए किन कुंजियों का उपयोग किया जा सकता है, और प्रत्येक तालिका के लिए सबसे अच्छा एक चुनें।
  • प्रत्येक तालिका के लिए, यह तय करें कि क्या एक मेज स्कैन एक कुंजी पर पढ़ना बेहतर है। यदि बहुत सारे रिकॉर्ड हैं जो कुंजी मूल्य से मेल खाते हैं, तो कुंजी के फायदे कम हो जाते हैं और टेबल स्कैन तेज हो जाता है।
  • उस क्रम को निर्धारित करें जिसमें क्वेरी में एक से अधिक तालिका मौजूद होने पर तालिकाओं को शामिल किया जाना चाहिए।
  • डेड कोड को समाप्त करने के लिए WHRE को फिर से लिखें, अनावश्यक संगणना को कम करने और जहाँ भी संभव हो बाधाओं को बदलने के लिए कुंजी का उपयोग करने का रास्ता खोलें।
  • जुड़ने से अप्रयुक्त तालिकाओं को हटा दें।
  • निर्धारित करें कि क्या कुंजियों का उपयोग किया जा सकता है ORDER BYऔर GROUP BY
  • उप-क्षेत्रों को सरल बनाने का प्रयास, साथ ही यह निर्धारित करता है कि उनके परिणामों को किस सीमा तक कैश किया जा सकता है।
  • मर्ज देखें (मैक्रो के रूप में दृश्य संदर्भ का विस्तार करें)

उसी पृष्ठ पर, यह निम्नलिखित कहता है:

MySQL ऑप्टिमाइज़र शब्दावली में, प्रत्येक क्वेरी जुड़ने का एक सेट है। जॉइन ज्वाइन शब्द का उपयोग SQL कमांड की तुलना में अधिक मोटे तौर पर किया जाता है। केवल एक मेज पर एक प्रश्न एक पतित जुड़ना है। यद्यपि हम आम तौर पर एक तालिका में शामिल होने के रिकॉर्ड को पढ़ने के बारे में नहीं सोचते हैं, पारंपरिक जोड़ के साथ उपयोग किए जाने वाले समान संरचना और एल्गोरिदम केवल एक तालिका के साथ क्वेरी को हल करने के लिए पूरी तरह से काम करते हैं।

उपसंहार

मौजूद कुंजियों के कारण, डेटा की मात्रा, और क्वेरी की अभिव्यक्ति, MySQL जॉइन्स कभी-कभी हमारे स्वयं के अच्छे (या हम पर वापस पाने के लिए) के लिए काम कर सकते हैं और उन परिणामों के साथ आते हैं जिनकी हम उम्मीद नहीं करते थे और जल्दी से समझा नहीं सकते।

मैंने इस विचित्रता के बारे में पहले भी लिखा था

क्योंकि MySQL क्वेरी ऑप्टिमाइज़र क्वेरी के मूल्यांकन के दौरान कुछ कुंजियों को खारिज कर सकता है।

@ फिल की टिप्पणी से मुझे यह उत्तर पोस्ट करने में मदद मिलेगी (+1 @ फिल की टिप्पणी के लिए)

@ ypercube की टिप्पणी (इसके लिए +1 भी) मेरी पोस्ट का एक कॉम्पैक्ट संस्करण है क्योंकि MySQL का क्वेरी ऑप्टिमाइज़र आदिम है। दुर्भाग्य से, यह तब से होना है क्योंकि यह बाहर के भंडारण इंजन से संबंधित है।

निष्कर्ष

आपके वास्तविक प्रश्न के लिए, MySQL क्वेरी ऑप्टिमाइज़र प्रत्येक क्वेरी के प्रदर्शन मैट्रिक्स को निर्धारित करेगा जब यह किया जाता है

  • गिनती की पंक्तियाँ
  • कुंजी का चयन करना
  • रुक-रुक कर परिणाम की मालिश
  • अरे हाँ, वास्तविक जोइन कर रहा है

संभवतः आपको क्वेरी को फिर से लिखना (रिफैक्टिंग) करके निष्पादन के क्रम को रोकना होगा

यहाँ पर आपने जो पहला Query दिया है

select count(*)
from   table1 a
join   table2 b
on     b.key_col=a.key_col
where  b.tag = 'Y';

पहले इसका मूल्यांकन करने के लिए इसे फिर से लिखने का प्रयास करें

select count(*)
from   table1 a
join   (select key_col from table2 where tag='Y') b
on     b.key_col=a.key_col;

यह निश्चित रूप से EXPLAIN योजना को बदल देगा। यह बेहतर या बदतर परिणाम उत्पन्न कर सकता है।

मैंने एक बार StackOverflow में एक सवाल का जवाब दिया जहां मैंने इस तकनीक को लागू किया था। EXPLAIN भयावह था लेकिन प्रदर्शन गतिशील था। यह केवल सही अनुक्रमित मौजूद होने और एक उपश्रेणी में लिमिट के उपयोग के कारण काम करता है

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


2
विस्तृत MySQL-विशिष्ट जानकारी के लिए +1 और विशेष रूप से मुझे "उपसंहार" और "निष्कर्ष" के बीच के अंतर को सीखने में प्रवृत्त करने के लिए!
बेलेव्यूबेकब

मेरे पोस्ट में, उपसंहार एक उप-निष्कर्ष है।
रोलैंडमाइसीडीडीबीए

6
@ रोलैंड: आप नवीनतम MariaDB (5.3 और 5.5) संस्करणों में और हाल ही में जारी मुख्य MySQL (5.6) संस्करण में ऑप्टिमाइज़र पर सुधार के बारे में एक परिणाम जोड़ सकते हैं । जो कुछ पुनर्लेखन को अनावश्यक बना सकता है।
ypercube y

1

ओरेकल के लिए, क्योंकि mySQL का एक लंबा विवरण था, हमें अनुकूलक का लाभ उठाने के 2 उच्च स्तर मिले हैं।

पहला नियम आधारित अनुकूलन (या RBO) है। ओरेकल में 15 सेट-इन-स्टोन नियम हैं जो प्रत्येक क्वेरी को निर्धारित क्रम में पालन करने का प्रयास करता है। यदि यह नियम 1 से एक अनुकूलित क्वेरी उत्पन्न नहीं कर सकता है, तो यह नियम 2 को आगे बढ़ाएगा और नियम 15 को हिट होने तक आगे बढ़ाएगा।

अधिक जानकारी के लिए: https://docs.oracle.com/cd/B10500_01/server.920/a96533/rbo.htm

ये ओरेकल आरडीबीएमएस गुठली को 11.1 से प्रभावित करते हैं और इससे नीचे मूल्य आधारित ऑप्टिमाइज़र (उर्फ सीबीओ) में परिवर्तित नहीं हुए हैं। Oracle 11.2 और इसके लिए CBO ऑप्टिमाइज़र की आवश्यकता होती है, लेकिन यदि उपयोगकर्ता चाहें तो पुराने SBO विधि में अनुकूलन के लिए विशिष्ट Sql ID को बाध्य कर सकता है।

Oracle 11.1+ के लिए CBO इसके बजाय एक ही SQL ID के लिए कई निष्पादन योजनाएँ बनाता है और कम से कम समग्र प्रत्याशित लागत के साथ निष्पादित करता है। यह आरबीओ से बहुत सारे तर्क का लाभ उठाता है, लेकिन डीबी के अंत उपयोगकर्ता को अपना डेटा प्रदान करने के लिए प्रत्येक ऑपरेशन के लिए गतिशील निष्पादन योजना लागत बनाने के लिए तालिका आँकड़ों का विश्लेषण करता है। बहुत बड़ी तालिकाओं पर पूर्ण तालिका स्कैन निष्पादित करना वास्तव में महंगा है; 10 पंक्तियों के साथ एक मेज पर पूर्ण तालिका स्कैन निष्पादित करना सस्ता है। RBO में इन्हें समान संचालन माना जाता था।

अधिक जानकारी के लिए: https://oracle-base.com/articles/misc/cost-based-optimizer-and-database-statistics

आपके विशिष्ट क्वेरी उदाहरण के लिए: Oracle संभवतः विभिन्न निष्पादन योजनाओं को बनाने के लिए जानकारी को पार्स करेगा और इस प्रकार एक तकनीकी रूप से दूसरे से बेहतर होगा। हालांकि, यह एक न्यूनतम अंतर हो सकता है। इसे देखते हुए, ओरेकल आरबीओ और सीबीओ दोनों क्वेरी 1 को अधिक पसंद करेंगे क्योंकि यह कम स्थितियों पर एक जॉइन को निष्पादित कर रहा है और फिर एक विशेष कॉलम को इसमें शामिल होने से बनी अस्थायी तालिका से फ़िल्टर कर रहा है।


1

यदि आपके पास दो प्रश्न हैं और आपको लगता है कि वे समकक्ष हैं तो निम्नलिखित हो सकते हैं:

  1. दोनों प्रश्नों का निष्पादन योजना समान है। यह ठीक है और यही हम उम्मीद करते हैं। चलो आशा करते हैं कि यह क्वेरी के लिए इष्टतम निष्पादन योजना है।
  2. अलग-अलग निष्पादन योजनाएं हैं। हमारे यहां दो उपकेंद्र हैं।

    2.1 प्रश्नों के निष्पादन की योजनाएँ अलग-अलग हैं लेकिन दोनों योजनाएँ समान रूप से अच्छी हैं। वह भी ठीक है। कोई आवश्यकता नहीं है कि समान प्रश्नों के लिए समान योजना बनाई जानी चाहिए। लेकिन प्रदर्शन बराबर होना चाहिए। और फिर से हम आशा करते हैं कि यह सबसे अच्छा संभव है।

    2.2 प्रश्नों के निष्पादन की योजनाएँ अलग हैं और एक योजना अन्य की तुलना में बेहतर है। फिर से हमारे पास उप-मामले हैं:

    २.२.१ योजनाएँ भिन्न हैं क्योंकि प्रश्न समतुल्य नहीं हैं। इसलिए ध्यान से देखें कि क्या वे वास्तव में समकक्ष हैं। आपके मामले में वे वास्तव में समकक्ष हैं।

    २.२.२ योजनाएँ भिन्न हैं लेकिन प्रश्न समतुल्य हैं। इसका मतलब यह है कि अनुकूलक पर्याप्त परिपक्व नहीं है। परफेक्ट ऑप्टिमाइज़र वाली परफेक्ट दुनिया में ऐसा नहीं होना चाहिए। तो हाँ, यह प्लेटफ़ॉर्म आश्रित है और आपको यह जानने के लिए प्लेटफ़ॉर्म विशिष्ट दस्तावेज़ों का अध्ययन करना होगा कि ऐसा क्यों होता है।

    २.२.३ योजनाएँ भिन्न हैं, प्रश्न समतुल्य हैं, डेटाबेस सॉफ्टवेयर में एक बग है।

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