2009-02-06 11 views
14

ठीक है तो मुझे एहसास है कि यह एक बहुत अस्पष्ट सवाल है, लेकिन मेरे साथ भालू।एसक्यूएल उप-इष्टतम क्वेरी प्लान का चयन क्यों करता है?

मैंने कई अवसरों पर विभिन्न और असंबद्ध प्रश्नों के साथ इस समस्या का अनुभव किया है। नीचे दिए गए क्वेरी कई मिनट लगते हैं निष्पादित करने के लिए:

SELECT <Fields> 
FROM <Multiple Tables Joined> 
    LEFT JOIN (SELECT <Fields> FROM <Multiple Tables Joined>) ON <Condition> 

हालांकि, सिर्फ संकेत शामिल हो यह सिर्फ सेकंड में कार्यान्वित क्वेरी जोड़कर:

SELECT <Fields> 
FROM <Multiple Tables Joined> 
    LEFT HASH JOIN (SELECT <Fields> FROM <Multiple Tables Joined>) ON <Condition> 

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

SELECT <Fields> 
FROM <Multiple Tables Joined> 
    LEFT JOIN dbo.MySubQueryFunction() ON <Condition> 

किसी के पास कोई विचार है कि इस मामले में अनुकूलक इतना मूर्ख क्यों है?

+0

SQL सर्वर का कौन सा संस्करण आप उपयोग कर रहे हैं? – Austin

+0

मैंने 2005 और 2008 दोनों में समस्या का अनुभव किया है –

उत्तर

13

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

यह तालिकाओं पर आंकड़ों की कमी के कारण ऐसा करता है।

+0

मैं तालिका चर का उपयोग नहीं कर रहा हूं लेकिन उप क्वेरी में अक्सर विचार होते हैं। हालांकि आपका तर्क मुझे समझ में आता है। –

+1

जब मैं शामिल संकेत को हटा देता हूं, तो क्वेरी योजना काफी बदलती है और यह नेस्टेड लूप पेश करती है। मुझे नहीं पता कि यह पंक्तियों का बुरा अनुमान कहां बना रहा है लेकिन मैं और अधिक समय व्यतीत नहीं कर सकता। –

7

अनुकूलक एक एल्गोरिदम है। यह गूंगा या स्मार्ट नहीं है, यह प्रोग्राम के तरीके के रूप में काम करता है।

Hash join का मतलब है कि एक छोटी पंक्ति स्रोत पर हैश तालिका बनाना, यही कारण है कि आंतरिक क्वेरी को पहले निष्पादित किया जाना चाहिए।

पहले मामले में अनुकूलक ने nested loop चुना होगा। इसने शामिल स्थिति को आंतरिक क्वेरी में धकेल दिया और एक अतिरिक्त भविष्यवाणी के साथ प्रत्येक पुनरावृत्ति पर आंतरिक क्वेरी निष्पादित की। यह इस predicate के लिए एक उचित सूचकांक नहीं मिल सकता है, और एक full table scan प्रत्येक पुनरावृत्ति पर किया गया था।

यह कहना मुश्किल है कि ऐसा क्यों होता है जब तक कि आप अपनी सटीक क्वेरी पोस्ट नहीं करते हैं और आपकी तालिका में कितनी पंक्तियां हैं।

एक टेबल फ़ंक्शन के साथ आंतरिक स्थिति में शामिल स्थिति को धक्का देना असंभव है, यही कारण है कि इसे केवल एक बार निष्पादित किया जा रहा है।

+0

मैं मानता हूं कि ऐसा होने वाला प्रतीत होता है। मुझे नहीं पता कि क्यों अनुकूलक नेस्टेड लूप करना चुनता है। –

+0

यह कहना मुश्किल है, हमें सटीक क्वेरी और तालिकाओं में कितनी पंक्तियां देखने की आवश्यकता है। – Quassnoi

+0

मैंने क्वेरी को कम करने की कोशिश की है, लेकिन सबसे छोटी मैं इसे तब भी प्राप्त कर सकता हूं जब समस्या को पुन: उत्पन्न करना 43 लाइनें हो।मैं डेटाबेस के बिना विश्लेषण करने की कोशिश करने के दर्द के माध्यम से किसी भी को नहीं रखना चाहता। –

-4

SQL सर्वर 2005 के अंदर: टी-एसक्यूएल क्वेरीिंग इन और कई अन्य सवालों के जवाब देती है। टी-एसक्यूएल डेटा पुनर्प्राप्ति और क्रिया प्रसंस्करण के हुड के नीचे बेहतरीन दिखने में से एक मैंने कभी देखा है। (नहीं, मैं पुस्तक का लेखक नहीं हूं, न ही मैं किसी भी लेखक या पुस्तक, या माइक्रोसॉफ्ट, या माइक्रोसॉफ्ट प्रेस के लेखकों से संबद्ध हूं। यह केवल एक अविश्वसनीय काम है, और विभिन्न डीबीए जिन्हें मैंने अतीत में बदल दिया है कुछ साल सहमत हैं।)

+0

मुझे इट्ज़िक पता है - वह शायद ग्रह पर सबसे बुद्धिमान एसक्यूएल लोगों में से एक है। – keithwarren7

संबंधित मुद्दे