यह पोस्ट पंक्ति लक्ष्यों के बारे में लेखों की एक श्रृंखला का हिस्सा है। आप अन्य भागों को यहाँ पा सकते हैं:
- भाग 1:पंक्ति लक्ष्य निर्धारित करना और उनकी पहचान करना
- भाग 2:सेमी जॉइन
इस भाग में बताया गया है कि ऑप्टिमाइज़र कब और क्यों एंटी जॉइन के लिए एक पंक्ति लक्ष्य प्रस्तुत करता है।
परिचय
एंटी जॉइन को एंटी सेमी जॉइन के रूप में भी जाना जाता है। यह प्रत्येक पंक्ति को इनपुट ए में शामिल होने से लौटाता है जिसके लिए कोई मिलान नहीं इनपुट बी पर पाया जा सकता है।
एंटी जॉइन के लिए:
- अनुकूलक हो सकता है लागू करने . के लिए एक आंतरिक-पक्ष पंक्ति लक्ष्य जोड़ें (सहसंबंधित नेस्टेड लूप जॉइन करते हैं) एंटी जॉइन केवल .
- एक पंक्ति लक्ष्य जोड़ा नहीं गया है गैर-सहसंबद्ध नेस्टेड लूप के लिए एंटी जॉइन, हैश एंटी जॉइन, या मर्ज एंटी जॉइन।
- हमेशा की तरह, कोई भी पंक्ति लक्ष्य केवल जोड़ा जाता है यदि यह बिना पंक्ति लक्ष्य लागू किए अनुमान से कम है।
- अनावश्यक आंतरिक पक्ष
TOP
खंड औरDISTINCT/GROUP BY
संचालन को सरल बनाया जा सकता है।
ऊपर दिए गए पहले बुलेट पर विस्तार करते हुए, सेमी जॉइन लागू करें और एंटी जॉइन रो लक्ष्यों को लागू करने के बीच मुख्य अंतर है:
- एक अर्ध जुड़ाव लागू करें हमेशा एक पंक्ति लक्ष्य प्रदान करता है (जब तक यह लक्ष्य के बिना अनुमान से कम है)।
- एक एंटी जॉइन लागू करें में एक पंक्ति लक्ष्य हो सकता है , लेकिन केवल तभी जब कोई तार्किक एंटी जॉइन लागत-आधारित अनुकूलन के दौरान लागू में रूपांतरित हो ।
मुझे खेद है कि ये नियम सरल नहीं हैं, लेकिन मैंने उन्हें नहीं बनाया। उम्मीद है कि कुछ चर्चा और उदाहरणों से यह सब स्पष्ट हो जाएगा।
डिफ़ॉल्ट रूप से कोई एंटी जॉइन रो लक्ष्य नहीं
अनुकूलक मानता है कि लोग अर्ध जुड़ाव . लिखते हैं (अप्रत्यक्ष रूप से उदाहरण के लिए EXISTS
. का उपयोग करना ) इस उम्मीद के साथ कि खोज की जा रही पंक्ति मिल जाएगी . एक लागू सेमी जॉइन पंक्ति लक्ष्य निर्धारित है उस अपेक्षित मिलान पंक्ति को शीघ्रता से खोजने में सहायता के लिए अनुकूलक द्वारा।
एंटी जॉइन . के लिए (उदाहरण के लिए NOT EXISTS
. का उपयोग करके व्यक्त किया गया ) अनुकूलक की धारणा यह है कि एक मेल खाने वाली पंक्ति नहीं मिलेगी . एक लागू विरोधी शामिल हों पंक्ति लक्ष्य निर्धारित नहीं है अनुकूलक द्वारा, क्योंकि यह यह पुष्टि करने के लिए सभी पंक्तियों की जांच करने की अपेक्षा करता है कि कोई मेल नहीं है।
यदि कोई मेल खाने वाली पंक्ति होती है, तो इस पंक्ति का पता लगाने में एंटी जॉइन लागू करने में अधिक समय लग सकता है, यदि पंक्ति लक्ष्य का उपयोग किया गया होता। फिर भी, जैसे ही (अप्रत्याशित) मैच का सामना करना पड़ता है, एंटी जॉइन अभी भी अपनी खोज को समाप्त कर देगा।
एंटी जॉइन रो लक्ष्य शर्तें लागू करें
SQL सर्वर हमें सीधे एंटी जॉइन लिखने का तरीका प्रदान नहीं करता है, इसलिए हमें NOT EXISTS
जैसे वर्कअराउंड का उपयोग करना होगा , NOT IN/ANY/SOME
, या EXCEPT
. इन रूपों में से प्रत्येक के परिणामस्वरूप क्वेरी संकलन की शुरुआत में पार्स किए गए पेड़ में एक सबक्वायरी प्रतिनिधित्व होता है। यह सबक्वायरी हमेशा एक लागू में अनियंत्रित होती है, और फिर एक तार्किक एंटी जॉइन में बदल जाती है जहां संभव हो (विवरण भाग 2 में चर्चा किए गए सेमी जॉइन के समान ही हैं)। यह सब तब होता है जब एक छोटी सी योजना पर भी विचार किया जाता है।
एक पंक्ति लक्ष्य प्राप्त करने के लिए एक विरोधी शामिल होने के लिए इसे प्रविष्ट . करना होगा तार्किक विरोधी जुड़ाव . के रूप में लागत-आधारित अनुकूलन (मतलब ऊपर दिए गए आवेदन से परिवर्तन सफल रहा होगा)। फिर, लागत-आधारित अनुकूलक को लागू करें . के रूप में तार्किक एंटी जॉइन को लागू करना चुनना चाहिए . ऐसा होने के लिए, अनुकूलक को पहले अन्वेषण . चुनना होगा लागू विकल्प; तो उसे चयन . करना होगा यह सबसे सस्ता विकल्प है (योजना के उस हिस्से के लिए)।
एक एंटी जॉइन रो लक्ष्य लागत-आधारित ऑप्टिमाइज़ेशन नियमों में से किसी एक द्वारा निर्धारित किया जाता है जो एक जॉइन को एक लागू में बदल सकता है। एक एंटी जॉइन जो प्रवेश करता है लागत-आधारित अनुकूलन लागू के रूप में (क्योंकि लॉजिकल एंटी जॉइन में रूपांतरण विफल) नहीं . होगा एक पंक्ति लक्ष्य लागू करें।
लागत-आधारित अनुकूलक केवल तभी लागू-से-शामिल विकल्प का पता लगाएगा और उसका चयन करेगा, जब किसी भी मेल खाने वाली आंतरिक पार्श्व पंक्तियों (जैसे किसी अनुक्रमणिका का उपयोग करके) का पता लगाने का एक प्रभावी तरीका हो। ऑप्टिमाइज़र विकल्प का पता नहीं लगाएगा यदि जॉइन इनर साइड सबट्री में "लैच ऑन" के लिए लागू विधेय के लिए उपयोगी कुछ भी नहीं है। यह एक सूचकांक, अस्थायी सूचकांक (एक उत्सुक सूचकांक स्पूल के माध्यम से), या अन्य तार्किक कुंजी हो सकता है। पंक्ति लक्ष्य जोड़ने से ऑप्टिमाइज़र को आवेदन करने के लिए शामिल होने के विकल्प की लागत का आकलन करने में मदद मिलती है, बशर्ते कि अधिकतम एक पंक्ति का पता लगाया जाना चाहिए।
ध्यान दें कि एक लागू एंटी जॉइन एक निष्पादन योजना में बिना पंक्ति लक्ष्य के दिखाई दे सकता है। ऐसा तब होता है जब लागू से जुड़ने के लिए प्रारंभिक परिवर्तन विफल हो जाता है, जैसा कि अपेक्षाकृत सामान्य है। जब ऐसा होता है, तो एंटी जॉइन लागत-आधारित ऑप्टिमाइज़र में एक लागू के रूप में जीवन शुरू करता है, और इसलिए इसमें शामिल होने के लिए लागू नियमों में से किसी एक द्वारा पंक्ति लक्ष्य कभी नहीं जोड़ा जाता है।
बेशक एक अलग तंत्र (लागू से संबद्ध नहीं) के माध्यम से इस आवेदन के अंदरूनी हिस्से पर एक पंक्ति लक्ष्य भी पेश किया जा सकता है, उदाहरण के लिए एक अलग शीर्ष ऑपरेटर द्वारा।
संक्षेप में:
- एक विरोधी जुड़ाव लागत-आधारित अनुकूलन (CBO) के दौरान केवल एक पंक्ति लक्ष्य प्राप्त कर सकता है।
- ऐन्टी जॉइन को लागू करने वाले नियम एक पंक्ति लक्ष्य जोड़ते हैं।
- एंटी जॉइन को सीबीओ में शामिल होने के रूप में दर्ज करना चाहिए, आवेदन के रूप में नहीं।
- सीबीओ को एक जॉइन के रूप में दर्ज करने के लिए, पहले के चरणों को सबक्वेरी को एक जॉइन (एक लागू चरण के माध्यम से) के रूप में फिर से लिखने में सक्षम होना चाहिए।
- CBO केवल आशाजनक मामलों में परिवर्तन लागू करने के लिए शामिल होने की खोज करता है।
उदाहरण
सेमी जॉइन लागू करने के मामले की तुलना में एंटी जॉइन लागू करने के लिए यह सब प्रदर्शित करना थोड़ा अधिक मुश्किल है। इसके कारणों को भाग 4 में शामिल किया जाएगा।
इस बीच, यहां एक एडवेंचरवर्क्स उदाहरण है जो दिखाता है कि अर्ध-जुड़ने के लिए एक ही अनियंत्रित ट्रेस झंडे का उपयोग करके पंक्ति लक्ष्य के साथ एक लागू विरोधी कैसे उत्पन्न होता है। लागत-आधारित अनुकूलन की शुरुआत में प्रारंभिक ज्ञापन संरचना दिखाने के लिए ट्रेस ध्वज 8608 जोड़ा गया है।
SELECT P.ProductID FROM Production.Product AS P WHERE NOT EXISTS ( SELECT 1 FROM Production.TransactionHistoryArchive AS THA WHERE THA.ProductID = P.ProductID UNION ALL SELECT 1 FROM Production.TransactionHistory AS TH WHERE TH.ProductID = P.ProductID ) OPTION (QUERYTRACEON 3604, QUERYTRACEON 8607, QUERYTRACEON 8608, QUERYTRACEON 8612, QUERYTRACEON 8621);
मौजूद सबक्वेरी को पहले एक लागू में बदल दिया जाता है: