जब मैं कोई संकेत जोड़ता हूं तो SQL सर्वर पंक्ति अनुमान क्यों बदलता है?


15

मेरे पास एक क्वेरी है जो कुछ तालिकाओं में मिलती है और बहुत बुरी तरह से प्रदर्शन करती है - पंक्ति अनुमान रास्ते (1000 बार) बंद होते हैं और नेस्टेड लूप शामिल होते हैं, जिसके परिणामस्वरूप कई टेबल स्कैन होते हैं। क्वेरी का आकार बिल्कुल सीधा है, कुछ इस तरह से दिख रहा है:

SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id 
WHERE t4.id = some_GUID

क्वेरी के साथ खेलते हुए, मैंने देखा कि जब मैंने इसे किसी एक जॉइन के लिए मर्ज ज्वाइन करने का संकेत दिया था, तो यह कई गुना तेज चलता है। यह मैं समझ सकता हूं - मर्ज ज्वाइन उस डेटा के लिए एक बेहतर विकल्प है जो शामिल हो गया है, लेकिन एसक्यूएल सर्वर सिर्फ यह अनुमान नहीं लगाता है कि एनओपी लूप्स को चुनना सही है।

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

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

UPD: अनाम निष्पादन योजनाएँ यहाँ देखी जा सकती हैं: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38stv0t7vjjfdp/no_hints_join.sqlplan?dqlplan?dq = 0

मैंने TF 3604, 9292 और 9204 का उपयोग करके दोनों प्रश्नों के आँकड़ों की जाँच की, और वे समान हैं। हालाँकि, अनुक्रमित / स्कैन किए गए अनुक्रमित प्रश्नों के बीच भिन्न होते हैं।

इसके अलावा, मैंने क्वेरी को चलाने की कोशिश की OPTION (FORCE ORDER)- यह मर्ज जॉइन का उपयोग करने की तुलना में भी तेजी से चलता है, प्रत्येक जॉइन के लिए एचएएसएचएचईएचएचएचएचएचचेक का चयन करता है।


3
क्या आपने देखा है कि आपके पास एक बाहरी जुड़ाव है लेकिन आप तब तालिका का उपयोग कहां कर रहे हैं?
जेम्स जेड

@ जेम्स- हां, मुझे इस बात की जानकारी है, मुझे नहीं लगता कि इसके साथ कोई समस्या है।
अलेक्जेंडर शेलीन

9
@AlexSh खैर, इसके साथ एक तार्किक / शब्दार्थ समस्या है, क्योंकि यह आपके बाहरी जोड़ को एक आंतरिक जुड़ाव में बदल देता है।
हारून बर्ट्रेंड

जवाबों:


21

विभिन्न लेखों और पुस्तकों को पढ़ने से, मैंने यह मान लिया था कि योजना बनने से पहले कार्डिनैलिटी का अनुमान लगाया जाता है।

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

हालांकि, बाद के अन्वेषण (लागत-आधारित अनुकूलन के दौरान), और अक्सर करते हैं, जिसके परिणामस्वरूप नए कार्डिनैलिटी अनुमानों की गणना की जाती है। ये बाद में सीईएस कम या ज्यादा 'सटीक' हो सकते हैं। यदि एक अनुमान के तहत परिणाम होता है, तो अनुकूलक एक ऐसी योजना चुन सकता है जो सस्ती दिखती है, लेकिन वास्तव में बहुत लंबे समय तक चलती है।

सामान्य तौर पर, इस बात की कोई गारंटी नहीं है कि शब्दार्थ रूप से समान उपप्रकार के लिए कार्डिनैलिटी का अनुमान समान परिणाम देगा। यह एक सांख्यिकीय प्रक्रिया है, सब के बाद, और कुछ संचालन में दूसरों की तुलना में गहरा सीई समर्थन है।

आपके मामले में, एक और कारक प्रतीत होता है - ऑप्टिमाइज़र एक शीर्ष का परिचय देता है (या चारों ओर घूमता है), जो उसके नीचे उप-रेखा पर एक पंक्ति लक्ष्य निर्धारित करता है:

योजना का टुकड़ा

यदि आप ट्रेस फ़्लैग 4138 (2008 R2 या बाद के संस्करण) को सक्षम करने के लिए थे , तो आप अनुमानों को अपेक्षाओं के साथ अधिक इन-लाइन पा सकते हैं, या शायद यह भी कि अनुकूलक अब नेस्टेड छोरों का चयन नहीं करेगा।

हालांकि, मैं जो देखता हूं, वह यह है कि मर्ज संकेत सभी अनुमानों को बहुत अधिक परिपूर्ण बनाता है।

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

इसके अलावा, मैंने क्वेरी को चलाने की कोशिश की OPTION (FORCE ORDER)- यह मर्ज जॉइन का उपयोग करने की तुलना में भी तेजी से चलता है, प्रत्येक जॉइन के लिए एचएएसएचएचईएचएचएचएचएचचेक का चयन करता है।

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

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

विस्तृत विश्लेषण के लिए मुझे अभी और अधिक समय की आवश्यकता होगी, और डेटाबेस की केवल एक आँकड़े-प्रति तक पहुँच होगी।


-10

जहाँ वामपंथियों की उपेक्षा की जाती है, वह आशावादी पर
क्यों भारी पड़ता है?
3 या अधिक से अधिक जुड़ने पर ऑप्टिमाइज़र रक्षात्मक होने के लिए TEND करेगा और लूप जॉइन करता है, जिससे मेमोरी की सुरक्षा
होती है और इसमें शामिल होने की स्थिति में लूप जॉइन होने की भी प्रवृत्ति होती है - क्या मेरे पास हर बार होने वाले कठिन साक्ष्य हैं - नहीं - अभी भी एक वास्तविकता है
कि जब आप कर सकते हैं तो कई जोड़ के साथ स्थिति को खींचते हैं जहाँ से जुड़ते हैं

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
  JOIN t4 
        ON t3.t4_id = t4.id 
       AND t4.id = some_GUID 

या इससे भी बेहतर अभी तक - मुझे यकीन है कि यह आपके संकेत या बल को पूरा करेगा या हरा देगा

SELECT t1.id
  FROM t1
  JOIN t2 
        ON t1.id = t2.t1_id
  JOIN t3 
        ON t2.id = t3.t2_id
       AND t3.t4_id = some_GUID

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

अलग-अलग अनुमान क्यों। एक अलग योजना। उन प्रश्नों से शुरू करें जो ऑप्टिमाइज़र को एक लड़ाई का मौका देते हैं।

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