कैसे और क्यों) TOP एक निष्पादन योजना को प्रभावित करता है?


35

मामूली जटिल क्वेरी के लिए मैं अनुकूलन करने की कोशिश कर रहा हूं, मैंने देखा कि TOP nक्लॉज हटाने से निष्पादन योजना बदल जाती है। मुझे लगता है कि जब एक प्रश्न शामिल अनुमान लगाया है | TOP nडेटाबेस इंजन क्वेरी अनदेखी चल पाएंगे TOPखंड, और फिर अंत में सिर्फ इतना है कि परिणाम के लिए नीचे सेट हटना एन पंक्तियों की संख्या है कि अनुरोध किया गया था। चित्रमय निष्पादन योजना यह इंगित करती है कि यह मामला है - TOP"अंतिम" चरण है। लेकिन ऐसा लगता है कि वहाँ अधिक चल रहा है।

मेरा सवाल है, कैसे (और क्यों) एक शीर्ष n खंड एक क्वेरी के निष्पादन योजना को प्रभावित करता है?

यहाँ एक सरल संस्करण है जो मेरे मामले में चल रहा है:

क्वेरी दो तालिकाओं, ए और बी से पंक्तियों का मिलान कर रही है।

TOPक्लॉज के बिना , ऑप्टिमाइज़र का अनुमान है कि तालिका A से 19k पंक्तियाँ होंगी और तालिका B से 46k पंक्तियाँ होंगी। लौटाई गई पंक्तियों की वास्तविक संख्या A के लिए 16k और B. A हैश मैच का उपयोग इन दो परिणाम सेटों में शामिल होने के लिए किया जाता है। कुल 69 पंक्तियाँ (तब एक प्रकार लागू होती है)। यह क्वेरी बहुत जल्दी होती है।

जब मैं TOP 1001ऑप्टिमाइज़र जोड़ता हूं तो हैश मैच का उपयोग नहीं करता है; इसके बजाय यह पहली बार तालिका ए (समान अनुमान / 19k / 16k का वास्तविक) से परिणाम सॉर्ट करता है और तालिका बी के खिलाफ नेस्टेड लूप करता है। तालिका बी के लिए पंक्तियों की अनुमानित संख्या अब 1 है, और अजीब बात यह है कि TOP nसीधे प्रभावित करती है बी के खिलाफ निष्पादन की अनुमानित संख्या (सूचकांक की तलाश) - यह हमेशा 2n + 1 या मेरे मामले में 2003 में प्रकट होता है । यदि मैं बदलता हूं तो यह अनुमान तदनुसार बदलता है TOP n। बेशक, चूंकि यह एक नेस्टेड है, निष्पादन की वास्तविक संख्या 16k है (तालिका ए से पंक्तियों की संख्या) और यह क्वेरी को धीमा कर देती है।

वास्तविक परिदृश्य थोड़ा अधिक जटिल है लेकिन यह मूल विचार / व्यवहार को दर्शाता है। दोनों तालिकाएँ अनुक्रमांक का उपयोग करके खोजी जाती हैं। यह SQL Server 2008 R2 एंटरप्राइज़ संस्करण है।


क्वेरी में एक ORDER BYक्लॉज है। TOPइस प्रकार की योजना में होने वाले परिवर्तनों को जोड़ते हुए, लेकिन मैं इस बारे में अधिक चिंतित हूं कि यह तालिका बी के खिलाफ सूचकांक के निष्पादन की संख्या को कैसे प्रभावित करता है ... (बेशक दोनों संबंधित हो सकते हैं - मुझे नहीं पता)
डेविड

1
संबंधित चर्चा: FAST num_rowsक्वेरी संकेत।
रेमस रूसु

जवाबों:


39

मैंने अनुमान लगाया होगा कि जब किसी क्वेरी में TOP n शामिल होता है, तो डेटाबेस इंजन TOP क्लॉज को अनदेखा करते हुए क्वेरी को रन करेगा, और फिर अंत में उस परिणाम को कम कर देगा, जो अनुरोध की गई पंक्तियों की संख्या के नीचे सेट है। चित्रमय निष्पादन योजना यह इंगित करती है कि यह मामला है - TOP "अंतिम" चरण है। लेकिन ऐसा लगता है कि वहाँ अधिक चल रहा है।

जिस तरह से ऊपर को अभिव्यक्त किया गया है, मुझे लगता है कि आपके पास एक गलत मानसिक तस्वीर हो सकती है कि क्वेरी कैसे निष्पादित होती है। एक क्वेरी योजना में एक ऑपरेटर एक कदम नहीं है (जहां पिछले चरण के पूर्ण परिणाम सेट का मूल्यांकन अगले एक द्वारा किया जाता है।

SQL सर्वर एक पाइपलाइन किए गए निष्पादन मॉडल का उपयोग करता है , जहां प्रत्येक ऑपरेटर Init () , GetRow () और Close () जैसे तरीकों को उजागर करता है । जैसा कि GetRow () नाम से पता चलता है, एक ऑपरेटर मांग पर एक समय में एक पंक्ति बनाता है (जैसा कि इसके मूल ऑपरेटर द्वारा आवश्यक है)। यह पुस्तकें ऑनलाइन लॉजिकल एंड फिजिकल ऑपरेटर्स संदर्भ में प्रलेखित है , मेरे ब्लॉग पोस्ट में और अधिक विस्तार के साथ क्यों प्रश्न योजनाएं पीछे की ओर चलती हैं । यह पंक्ति-ए-टाइम मॉडल क्वेरी निष्पादन के लिए ध्वनि अंतर्ज्ञान बनाने में आवश्यक है।

मेरा सवाल है, कैसे (और क्यों) TOPएन क्लॉज़ किसी क्वेरी के निष्पादन योजना को प्रभावित करता है ?

कुछ लॉजिकल ऑपरेशंस जैसे TOP, सेमी जॉइन और FAST n क्विक हिंट , क्वेरी ऑप्टिमाइज़र के एक्जीक्यूशन प्लान के ऑल्टरनेटिव्स को प्रभावित करने के तरीके को प्रभावित करते हैं। मूल विचार यह है कि एक संभव योजना आकार पहले n पंक्तियों को एक अलग योजना की तुलना में अधिक तेज़ी से वापस कर सकता है जो सभी पंक्तियों को वापस करने के लिए अनुकूलित किया गया था।

उदाहरण के लिए, अनुक्रमित नेस्टेड छोरों में शामिल होने के लिए अक्सर छोटी संख्या में पंक्तियों को वापस करने का सबसे तेज़ तरीका होता है, हालांकि स्कैन के साथ हैश या मर्ज जुड़ना बड़े सेट पर अधिक कुशल हो सकता है। इन विकल्पों के बारे में क्वेरी ऑप्टिमाइज़र जिस तरह से संचालन के तार्किक पेड़ में एक विशेष बिंदु पर एक पंक्ति लक्ष्य निर्धारित करके है ।

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

उदाहरण के लिए, एक तार्किक TOP(10) लॉजिकल क्वेरी ट्री में एक विशेष बिंदु पर 10 का एक पंक्ति लक्ष्य सेट करता है। पंक्ति लक्ष्य तक पहुंचने वाले ऑपरेटरों की लागत को अनुमान लगाने के लिए संशोधित किया जाता है कि पंक्ति लक्ष्य को पूरा करने के लिए उन्हें कितनी पंक्तियों का उत्पादन करने की आवश्यकता होती है। यह गणना जटिल बन सकती है, इसलिए इसे पूरी तरह से काम करने वाले उदाहरण और एनोटेट निष्पादन योजनाओं के साथ समझना आसान है । पंक्ति के लक्ष्यों में शामिल होने के विकल्प की तुलना में अधिक प्रभावित हो सकता है या क्या स्कैन की तलाश और लुकअप पसंद किए जाते हैं। उस पर अधिक जानकारी यहाँ

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

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

आपकी विशेष क्वेरी और योजना यहां विस्तृत विश्लेषण के लिए उपयुक्त नहीं हो सकती है (यदि आप चाहें तो हर तरह से वास्तविक निष्पादन योजना प्रदान करें) लेकिन उम्मीद है कि यहां उल्लिखित विचार आपको आगे बढ़ने की अनुमति देंगे।


12

जब आप TOP का उपयोग करते हैं, तो ऑप्टिमाइज़र कम काम करने का अवसर देखता है। यदि आप 10 पंक्तियों के लिए पूछते हैं, तो एक अच्छा मौका है कि इसे पूरे सेट का उपभोग करने की आवश्यकता नहीं है। इसलिए TOP ऑपरेटर को दाईं ओर बहुत आगे बढ़ाया जा सकता है। यह अगले ऑपरेटर (इसके दाईं ओर) से पंक्तियों का अनुरोध करता रहेगा, जब तक कि यह पर्याप्त प्राप्त न हो जाए।

आप बताते हैं कि TOP के बिना, क्वेरी बहुत अंत में डेटा को सॉर्ट करती है। यदि इंजन को पता चल सकता है कि अग्रिम में शामिल होने से कितनी पंक्तियाँ संतुष्ट होने वाली थीं, तो यह एक समान योजना का उपयोग करने के लिए चुन सकता है, बाईं ओर टीओपी की स्थिति। लेकिन हैश मैच को अपेक्षाकृत अधिक करने के प्रयास के साथ, और संभवतः मर्ज जॉइन के लिए कोई विकल्प नहीं है, ऑप्टिमाइज़र शीर्ष को दाईं ओर आगे फ़िल्टर करना पसंद कर सकता है।

जब टेबल बी को क्वेर किया जाता है, तो यह एक बार में एक ही पंक्ति को ला रहा है। इसलिए अनुमान १ है। यह भी मानता है कि यह केवल ५०% पंक्ति को ही खोजेगा। तो यह अनुमान लगाता है कि इसे खोजने के लिए 2n + 1 की आवश्यकता होगी।


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

"पंक्तियों की अनुमानित संख्या" निष्पादन के अनुसार है। नेस्टेड लूप में, यह एक से अधिक बार निष्पादित होने की काफी संभावना है।
रोब फार्ले

यह वास्तविक संख्या पंक्तियों की संख्या और तब निष्पादन की वास्तविक संख्या की तुलना में अलग व्यवहार होगा। यदि वास्तविक योजना 16,834 वास्तविक निष्पादन दिखाती है और 15,407 वास्तविक पंक्तियाँ वापस आती हैं, तो मुझे इसका मतलब यह लगता है कि इसने 16k खोजे, लेकिन केवल 15k को विधेय से मिला। यदि इसका अर्थ प्रति निष्पादन 15k पंक्तियाँ है तो यह 15k * 16k = 240 मिलियन पंक्तियाँ होंगी - तालिका से लगभग 10 गुना बड़ी ...
David

इसके अलावा, मुझे यकीन नहीं है कि मैं आपके उत्तर के अंतिम कथन का पालन करूंगा। जब आप कहते हैं कि 2n + 1 "इसे" ढूंढता है, तो आपको "यह" से क्या मतलब है? निश्चित रूप से एक पंक्ति नहीं है? क्या आपका मतलब है कि ऑप्टिमाइज़र मानता है कि ए में किसी भी पंक्ति के लिए 50% संभावना है कि इसे बी से मिलान किया जाएगा और इसलिए उसे बी से 1001 मैच प्राप्त करने के लिए ए से 2003 की पंक्तियों को "कोशिश" करने की आवश्यकता होगी? क्या यह व्यवहार Microsoft द्वारा कहीं भी प्रलेखित है? और इसका TOPखंड से क्या लेना-देना है? आपके उत्तर के लिए धन्यवाद / धैर्य।
डेविड

हां, अनुमानित पंक्तियां प्रति निष्पादन है। वास्तविक पंक्तियाँ कुल हैं। हालाँकि, किसी ऑपरेटर को तालिका में अधिक पंक्तियों को वापस करने में कोई समस्या नहीं है, क्योंकि कई बार एक ही पंक्ति को चलाने वाले ऑपरेटरों को प्रदर्शित करना बहुत आसान है।
रॉब फार्ले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.