2009-09-25 15 views
5

मैं एक बहुत जटिल संग्रहित प्रक्रिया को डीबग करने की कोशिश कर रहा हूं जो कई टैबलेट (10-11) में शामिल हो जाता है। मैं देख रहा हूं कि पेड़ के एक हिस्से के लिए पंक्तियों की अनुमानित संख्या पंक्तियों की वास्तविक संख्या से काफी अलग है - इसके सबसे खराब SQL सर्वर का अनुमान है कि 1 पंक्ति वापस आ जाएगी, जब वास्तविकता में 55,000 पंक्तियां वापस आती हैं!एसक्यूएल सर्वर पंक्तियों की अनुमानित संख्या कैसे काम करता है?

मैं यह काम करने की कोशिश कर रहा हूं कि यह क्यों है - मेरे सभी आंकड़े अद्यतित हैं, और मैंने कई तालिकाओं पर एक पूर्णस्कैन के साथ आंकड़े अपडेट किए हैं। मैं किसी भी उपयोगकर्ता परिभाषित कार्यों या तालिका चर का उपयोग नहीं कर रहा हूँ। जहां तक ​​मैं देख सकता हूं कि SQL सर्वर वास्तव में अनुमान लगा सकता है कि कितनी पंक्तियां वापस आने जा रही हैं, लेकिन यह एक ऐसी योजना चुनना जारी रखती है जो हजारों आरडीआई लुकअप करने के लिए करती है (जब यह केवल 1 प्रदर्शन करने की अपेक्षा करता है या 2)।

मैं कोशिश करने और समझने के लिए क्या कर सकता हूं कि पंक्तियों की अनुमानित संख्या इतनी अधिक क्यों है?

अद्यतन: तो योजना मैं विशेष रूप से एक नोड पाया है जो suspicous लगता है पर देख रहे हैं - अपनी एक मेज निम्नलिखित predecate का उपयोग कर एक मेज पर स्कैन:

status <> 5 
AND [type] = 1 
OR [type] = 2 

यह विधेय पूरे तालिका लौटाता है (630 पंक्तियां - तालिका स्वयं को खराब प्रदर्शन का स्रोत नहीं स्कैन करती है) हालांकि SQL सर्वर की अनुमानित संख्या पंक्तियों की संख्या 37 है। SQL सर्वर तब आरडीआई लुकअप, इंडेक्स स्कैन और इंडेक्स पर इसके साथ कई नेस्टेड लूप करने जा रहा है। प्रयास है। क्या यह मेरे बड़े पैमाने पर गलत अनुमान का स्रोत हो सकता है? पंक्तियों की एक और समझदार संख्या का अनुमान लगाने के लिए मैं इसे कैसे प्राप्त करूं?

+0

आप पोस्ट कृपया सकते हैं अपनी मेज परिभाषा और पूर्ण क्वेरी को हल कर सकते हैं? – Quassnoi

+0

क्षमा करें, लेकिन वास्तव में नहीं - यह बहुत बड़ा है (250 लाइन एसपी + 10 टेबल)। – Justin

+3

यदि आपका भविष्य बिल्कुल ठीक है (कोई ब्रैकेट नहीं) तो आपके पास तर्क समस्या हो सकती है। और ओआर पर प्राथमिकता लेता है। होना चाहिए [स्थिति] <> 5 और (टाइप = 1 या टाइप = 2) – GilaMonster

उत्तर

8

SQL Server विभाजन निम्न डेटा के साथ करने के लिए 200 श्रेणियों में प्रत्येक सूचकांक (here से):

  • RANGE_HI_KEY

    एक हिस्टोग्राम चरण की ऊपरी सीमा दिखाते हुए एक महत्वपूर्ण मूल्य।

  • RANGE_ROWS

    निर्दिष्ट करती है कि कई पंक्तियों सीमा के अंदर हैं (वे इस RANGE_HI_KEY की तुलना में छोटे हैं, लेकिन पिछले छोटे RANGE_HI_KEY से भी बड़ा कर रहे हैं)।

  • EQ_ROWS

    निर्दिष्ट करती है कि कई पंक्तियों बिल्कुल RANGE_HI_KEY के बराबर हैं।

  • AVG_RANGE_ROWS

    सीमा के अंदर अलग मूल्य प्रति पंक्तियों की औसत संख्या।

  • DISTINCT_RANGE_ROWS

    निर्दिष्ट करती है कि कई अलग कुंजी मान इस सीमा (पिछले कुंजी RANGE_HI_KEY और RANGE_HI_KEY खुद से पहले शामिल नहीं) के अंदर कर रहे हैं;

आमतौर पर, सबसे अधिक आबादी वाले मूल्यों RANGE_HI_KEY में जाने।

हालांकि, वे सीमा में शामिल हो सकते हैं और इससे वितरण में कमी हो सकती है।

इन आंकड़ों (दूसरों के बीच) की कल्पना कीजिए:

पंक्तियों की कुंजी मूल्य गणना

1   1 
2   1 
3   10000 
4   1 

SQL Server आम तौर पर दो श्रेणियों को बनाता है: 13 और 4 अगले आबादी वाले मूल्य है, जो इन आँकड़ों में आता है करने के लिए करने के लिए :

RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS 
3    2   10000 1    2 

, जिसका मतलब है कि खोज करते समय, 2, लेकिन 1 पंक्ति है और यह सूचकांक पहुंच का उपयोग करने के लिए बेहतर है।

लेकिन 3 सीमा के अंदर चला जाता है, आंकड़े ये हैं:

RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS 
4    10002  1  3334   3 

अनुकूलक सोचता है कि वहाँ कुंजी 2 के लिए 3334 पंक्तियों कर रहे हैं और सूचकांक का उपयोग काफी महंगी है।

+0

पूर्ण स्कैन वाले आंकड़ों को अपडेट करने के बावजूद हम इस समस्या को कैसे हल कर सकते हैं? – Meysam

+0

@Maysam: आप अक्सर उपयोग की जाने वाली भविष्यवाणियों के लिए 'CREATE सांख्यिकी' का उपयोग कर सकते हैं। – Quassnoi

0

के बाद से आप पहले से ही आंकड़ों को अपडेट, मैं किसी भी पैरामीटर सूँघने को खत्म करने की कोशिश करेंगे:

CREATE PROCEDURE xyz 
(
    @param1 int 
    ,@param2 varchar(10) 

)AS 

DECLARE @param_1 int 
     ,@param_2 varchar(10) 

SELECT @[email protected] 
     ,@[email protected] 

...complex query here.... 
...WHERE [email protected]_1 AND [email protected]_2.... 

go 
3

यह आंकड़े का उपयोग करता है, जो यह प्रत्येक सूचकांक के लिए रहता है।

(तुम भी गैर अनुक्रमित स्तंभ पर आँकड़े बना सकते हैं)

एक डाटाबेस (चेतावनी में हर मेज पर अपने सभी आंकड़ों को अपडेट करने के लिए:। बहुत बड़ी डेटाबेस पर कुछ समय लगेगा ऐसा मत करो अपने डीबीए के साथ की जाँच के बिना उत्पादन सर्वर पर ...):

exec sp_msforeachtable 'UPDATE STATISTICS ?' 

आप अपने सबसे अधिक सक्रिय अनुक्रमित (आवेशण या नष्टकरण की यानी बहुत सारे के पुनर्निर्माण के लिए एक नियमित रूप से अनुसूचित काम) नहीं है, तो आप के पुनर्निर्माण पर विचार करना चाहिए अपने इंडेक्स (उपरोक्त के रूप में एक ही चेतावनी लागू होती है):

exec sp_msforeachtable "DBCC DBREINDEX('?')" 
0

अपने अनुक्रमित पुनर्निर्माण गलत अनुमान पंक्तियों मूल्य मुद्दा

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