नेस्टेड लूप केवल समर्थन छोड़ दिए गए जॉइन में क्यों शामिल होता है?


11

क्रेग फ्रीडमैन के ब्लॉग, नेस्टेड लूप्स जॉइन में , वह बताते हैं कि नेस्टेड लूप्स ज्वाइन क्यों नहीं एक सही बाहरी जुड़ाव का समर्थन कर सकते हैं:

समस्या यह है कि हम आंतरिक तालिका को कई बार स्कैन करते हैं - एक बार बाहरी पंक्ति की प्रत्येक पंक्ति के लिए। हम इन एकाधिक स्कैन के दौरान कई बार एक ही आंतरिक पंक्तियों का सामना कर सकते हैं। किस बिंदु पर हम निष्कर्ष निकाल सकते हैं कि एक विशेष आंतरिक पंक्ति शामिल नहीं हुई है या नहीं?

क्या कोई कृपया इसे वास्तव में सरल और शैक्षिक तरीके से समझा सकता है?

क्या इसका मतलब है कि लूप बाहरी तालिका ( R1) और आंतरिक ( R2) स्कैन से शुरू होता है ?

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

एसक्यूएल सर्वर तथ्य का अनुकूलन में करता है (और अक्सर बदल देता है) RIGHT JOINके साथ LEFT JOINहै, लेकिन सवाल क्यों यह है समझाने के लिए है तकनीकी रूप से असंभव एक के लिए NESTED LOOPS JOINउपयोग करने के लिए / समर्थन RIGHT JOINतर्क।

जवाबों:


12

यहां मुख्य मुद्दा एक बाहरी जुड़ाव का कार्यान्वयन है, नेस्टेड छोरों का उपयोग करके, तकनीकी तरीके से जो तार्किक तरीके के विपरीत है , जहां आंतरिक तालिका बाहरी लूप के माध्यम से और बाहरी तालिका आंतरिक लूप के माध्यम से एक्सेस की जाती है ।

टेबल ए और बी को देखते हुए, आइए इसे लागू करें A LEFT JOIN B

A
--
1
2

B
_
1
3

सबसे पहले, इसे " प्राकृतिक " तरीके से करते हैं।

हम ए के माध्यम से पुनरावृति करते हैं।
हम रिकॉर्ड 1 तक
पहुंचते हैं।
हम बी के माध्यम से पुनरावृत्ति करते हैं। हम बी में रिकॉर्ड 1 और आउटपुट 1-1 पाते हैं ।

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

अब, इसे " विपरीत " तरीके से करते हैं।

हम बी के माध्यम से पुनरावृत्ति करते हैं।
हम रिकॉर्ड 1 तक
पहुंचते हैं।
हम ए के माध्यम से पुनरावृत्ति करते हैं। हम रिकॉर्ड 1 को ए और आउटपुट 1-1 में पाते हैं ।

हम बी के माध्यम से पुनरावृत्ति करते रहते हैं।
हम रिकॉर्ड 3 एक्सेस करते हैं

हम ए के माध्यम से पुनरावृत्ति करते हैं। हम ए में कोई मैच नहीं पाते हैं।

अब याद रखें कि यह था A LEFT JOIN B, जिसका अर्थ है कि 1-1 के अलावा हमें 2-नल का उत्पादन करना चाहिए ।
समस्या यह है कि उस बिंदु पर, हमें पता नहीं है कि किस आईडी आईडी के लिए हमारे पास पहले से ही एक मैच है (1) और किन रिकॉर्डों के लिए हम (2) नहीं हैं।


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


13

लिंक किए गए लेख में मुझे जो पसंद नहीं है वह कथन है कि "नेस्टेड लूप जॉइन एल्गोरिथम सही जुड़ने के तार्किक जुड़ने वाले ऑपरेटर का समर्थन नहीं करता है"

जबकि एक सीमा है, इस बिंदु पर शब्दांकन थोड़ा भ्रमित करने वाला है। मुझे आशा है कि निम्नलिखित बातें बेहतर बताती हैं:

नेस्टेड लोप जॉइन एल्गोरिथ्म में दो टेबल शामिल हैं (चाहे पिछले ऑपरेशन के बेस टेबल या रिजल्ट सेट अप्रासंगिक हैं) जिन्हें बाहरी और भीतरी तालिका नाम दिया गया है और उन्हें एल्गोरिथ्म द्वारा अलग तरीके से व्यवहार किया जाता है ("बाहरी" तालिका बाहरी पर ट्रेस होती है) लूप और आंतरिक छोरों पर "आंतरिक" तालिका)।

तो, हम कहते हैं कि हमारे पास एक जुड़ाव है:

A (some_type) JOIN B

एल्गोरिथ्म को भी निष्पादित किया जा सकता है:

outer-loop-A  nested-loop  inner-loop-B

या:

outer-loop-B  nested-loop  inner-loop-A

अब, अगर ( some_type) शामिल है INNERया CROSSनहीं है, तो कोई सीमा नहीं है, तो योजनाकार दो तरीकों में से किसी एक को चुन सकता है (अलग-अलग प्रदर्शन विशेषताओं के साथ, सेट के आकार के आधार पर, शामिल किए गए कॉलम, इंडेक्स आदि के मूल्यों का वितरण। । आमतौर पर सबसे छोटी तालिका को एल्गोरिथ्म में "बाहरी" तालिका चुना जाएगा)।

लेकिन जब शामिल हो some_typeजाता है LEFT, तो यह केवल उपयोग कर सकता है:

outer-loop-A  nested-loop  inner-loop-B

और नहीं

outer-loop-B  nested-loop  inner-loop-A

और चूंकि RIGHTहमेशा एक जुड़ाव के रूप में फिर से लिखा जा सकता है LEFT, इसलिए इसकी एक ही सीमा है, उल्टा। के लिए A RIGHT JOIN B(जिसे फिर से लिखा जा सकता है B LEFT JOIN A) यह केवल उपयोग कर सकता है:

outer-loop-B  nested-loop  inner-loop-A

और चारों ओर नहीं *

एक ही सीमा बाएं-अर्धविराम, बायां-विरोधी-अर्धविक्षिप्त, दायां-अर्धविक्षिप्त और दायां-विरोधी- अर्धविराम के लिए लागू होती है।

FULLदूसरी ओर में शामिल होने के लिए सीधे एक नेस्टेड पाश के साथ संभाला नहीं जा सकता एल्गोरिथ्म में शामिल हो। लेख बहुत अच्छी तरह से समझाता है (यह अंत के पास है) कि कैसे एक पूर्ण जोड़ को फिर से लिखा जा सकता है (और अनुकूलक द्वारा) एक बाईं जोड़ के एक संघ और एक बाएं विरोधी अर्धविराम जो तब दो नेस्टेड छोरों (और के रूप में योजना बनाई जा सकती है) संघ)।

* जैसा कि डूडू मार्कोविट्ज़ अपने जवाब में बताते हैं, रिवर्स तरीका इस्तेमाल किया जा सकेगा, लेकिन केवल तभी जब हम नेस्टेड-लूप को एक अतिरिक्त संरचना और अंत में एक अतिरिक्त कदम रखने के लिए एल्गोरिथ्म में बदल दें।


खैर, यह बहुत स्पष्ट किया। आपका उत्तर डूडू M के साथ संयुक्त है: इसे बहुत अच्छी तरह से समझाता है!
गॉर्डन लिली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.