मेरे पास एक क्वेरी है जो कुछ तालिकाओं में मिलती है और बहुत बुरी तरह से प्रदर्शन करती है - पंक्ति अनुमान रास्ते (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)
- यह मर्ज जॉइन का उपयोग करने की तुलना में भी तेजी से चलता है, प्रत्येक जॉइन के लिए एचएएसएचएचईएचएचएचएचएचचेक का चयन करता है।