मेरे पास कुछ हद तक जटिल SQL Server 2008 क्वेरी (काफी घनी एसक्यूएल की लगभग 200 लाइनें) हैं जो मुझे इसकी आवश्यकता नहीं थी। समय के साथ, प्रदर्शन लगभग 5 सेकंड से लगभग 2 सेकंड तक गिरा।
निष्पादन योजना पर एक नज़र डालते हुए, यह बहुत स्पष्ट था कि जोड़ों को फिर से व्यवस्थित करके, प्रदर्शन में सुधार किया जा सकता है। मैंने किया, और यह किया ... लगभग 3 सेकंड के लिए। अब क्वेरी में "विकल्प बल आदेश" संकेत है , और जीवन अच्छा है।
आज मेरे साथ आता है, डेटाबेस की सफाई। मैं लगभग 20% पंक्तियों को संग्रहीत करता हूं, पंक्तियों को हटाने के अलावा संबंधित डेटाबेस में कोई कार्रवाई नहीं करता है ... निष्पादन योजना पूरी तरह से ठीक हो जाती है । यह पूरी तरह से गलतफहमी है कि कुछ पंक्तियाँ कुछ उपप्रकार वापस आएंगी, और (उदाहरण के लिए) एक की जगह:
<Hash>
साथ में
<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>
अब क्वेरी समय लगभग .3s से लेकर 18s तक होता है। (!) सिर्फ इसलिए कि मैंने पंक्तियों को हटा दिया। अगर मैं क्वेरी संकेत निकालता हूं तो मैं लगभग 2s क्वेरी समय पर वापस आ जाता हूं। बेहतर है, लेकिन बदतर।
मैंने डेटाबेस को कई स्थानों और सर्वरों पर पुनर्स्थापित करने के बाद समस्या को पुन: प्रस्तुत किया है। बस प्रत्येक तालिका से लगभग 20% पंक्तियों को हटाने से हमेशा यह समस्या होती है।
- क्या क्वेरी अनुमानों को पूरी तरह से गलत बनाने के लिए एक मजबूर ज्वाइन ऑर्डर के लिए यह सामान्य है (और इस तरह क्वेरी अप्रत्याशित है)?
- क्या मुझे यह उम्मीद करनी चाहिए कि मुझे या तो सब-इष्टतम क्वेरी प्रदर्शन स्वीकार करना होगा, या इसे बाज की तरह देखना होगा और अक्सर मैन्युअल रूप से क्वेरी संकेत संपादित करना होगा? या हो सकता है हर संकेत के रूप में अच्छी तरह से शामिल हों? .3s से 2 s एक बड़ी हिट लेने के लिए है।
- क्या यह स्पष्ट है कि ऑप्टिमाइज़र ने पंक्तियों को हटाने के बाद क्यों उड़ा दिया? उदाहरण के लिए, "हाँ, इसने एक नमूना स्कैन लिया, और क्योंकि मैंने डेटा इतिहास में पहले की अधिकांश पंक्तियों को संग्रहीत किया था, जो नमूना विरल परिणाम देता था, इसलिए इसने एक हल किए गए हैश ऑपरेशन की आवश्यकता को कम करके आंका"?
यदि आप निष्पादन योजनाओं को देखना चाहते हैं, तो कृपया एक स्थान सुझाएं जो मैं उन्हें पोस्ट कर सकता हूं। अन्यथा, मैंने सबसे आश्चर्यजनक बिट का नमूना लिया है। यहाँ मूलभूत गलत अनुमान है, परेंस में संख्याएँ (अनुमानित: वास्तविक) पंक्तियाँ हैं।
/ Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
\ NonClustered Index Seek (1:7229)
ध्यान दें कि आंतरिक लूप 908 पंक्तियों को स्कैन करने की उम्मीद है, लेकिन इसके बजाय 52,258,441 स्कैन करता है। यदि यह सटीक होता, तो यह शाखा 12sec के बजाय, लगभग 2ms तक चलती। पंक्तियों को हटाने से पहले, यह आंतरिक जुड़ाव अनुमान केवल 2 के कुल कारक द्वारा बंद था, और दो क्लस्टर इंडेक्स पर हैश मैच के रूप में प्रदर्शन किया गया था।