विकल्प बल आदेश पंक्ति को हटाए जाने तक प्रदर्शन में सुधार करता है


9

मेरे पास कुछ हद तक जटिल SQL Server 2008 क्वेरी (काफी घनी एसक्यूएल की लगभग 200 लाइनें) हैं जो मुझे इसकी आवश्यकता नहीं थी। समय के साथ, प्रदर्शन लगभग 5 सेकंड से लगभग 2 सेकंड तक गिरा।

निष्पादन योजना पर एक नज़र डालते हुए, यह बहुत स्पष्ट था कि जोड़ों को फिर से व्यवस्थित करके, प्रदर्शन में सुधार किया जा सकता है। मैंने किया, और यह किया ... लगभग 3 सेकंड के लिए। अब क्वेरी में "विकल्प बल आदेश" संकेत है , और जीवन अच्छा है।

आज मेरे साथ आता है, डेटाबेस की सफाई। मैं लगभग 20% पंक्तियों को संग्रहीत करता हूं, पंक्तियों को हटाने के अलावा संबंधित डेटाबेस में कोई कार्रवाई नहीं करता है ... निष्पादन योजना पूरी तरह से ठीक हो जाती है । यह पूरी तरह से गलतफहमी है कि कुछ पंक्तियाँ कुछ उपप्रकार वापस आएंगी, और (उदाहरण के लिए) एक की जगह:

<Hash>

साथ में

<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>

अब क्वेरी समय लगभग .3s से लेकर 18s तक होता है। (!) सिर्फ इसलिए कि मैंने पंक्तियों को हटा दिया। अगर मैं क्वेरी संकेत निकालता हूं तो मैं लगभग 2s क्वेरी समय पर वापस आ जाता हूं। बेहतर है, लेकिन बदतर।

मैंने डेटाबेस को कई स्थानों और सर्वरों पर पुनर्स्थापित करने के बाद समस्या को पुन: प्रस्तुत किया है। बस प्रत्येक तालिका से लगभग 20% पंक्तियों को हटाने से हमेशा यह समस्या होती है।

  1. क्या क्वेरी अनुमानों को पूरी तरह से गलत बनाने के लिए एक मजबूर ज्वाइन ऑर्डर के लिए यह सामान्य है (और इस तरह क्वेरी अप्रत्याशित है)?
  2. क्या मुझे यह उम्मीद करनी चाहिए कि मुझे या तो सब-इष्टतम क्वेरी प्रदर्शन स्वीकार करना होगा, या इसे बाज की तरह देखना होगा और अक्सर मैन्युअल रूप से क्वेरी संकेत संपादित करना होगा? या हो सकता है हर संकेत के रूप में अच्छी तरह से शामिल हों? .3s से 2 s एक बड़ी हिट लेने के लिए है।
  3. क्या यह स्पष्ट है कि ऑप्टिमाइज़र ने पंक्तियों को हटाने के बाद क्यों उड़ा दिया? उदाहरण के लिए, "हाँ, इसने एक नमूना स्कैन लिया, और क्योंकि मैंने डेटा इतिहास में पहले की अधिकांश पंक्तियों को संग्रहीत किया था, जो नमूना विरल परिणाम देता था, इसलिए इसने एक हल किए गए हैश ऑपरेशन की आवश्यकता को कम करके आंका"?

यदि आप निष्पादन योजनाओं को देखना चाहते हैं, तो कृपया एक स्थान सुझाएं जो मैं उन्हें पोस्ट कर सकता हूं। अन्यथा, मैंने सबसे आश्चर्यजनक बिट का नमूना लिया है। यहाँ मूलभूत गलत अनुमान है, परेंस में संख्याएँ (अनुमानित: वास्तविक) पंक्तियाँ हैं।

                             /  Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
                             \  NonClustered Index Seek (1:7229)

ध्यान दें कि आंतरिक लूप 908 पंक्तियों को स्कैन करने की उम्मीद है, लेकिन इसके बजाय 52,258,441 स्कैन करता है। यदि यह सटीक होता, तो यह शाखा 12sec के बजाय, लगभग 2ms तक चलती। पंक्तियों को हटाने से पहले, यह आंतरिक जुड़ाव अनुमान केवल 2 के कुल कारक द्वारा बंद था, और दो क्लस्टर इंडेक्स पर हैश मैच के रूप में प्रदर्शन किया गया था।

जवाबों:


6

क्या क्वेरी अनुमानों को पूरी तरह से गलत बनाने के लिए एक मजबूर ज्वाइन ऑर्डर के लिए यह सामान्य है (और इस तरह क्वेरी अप्रत्याशित है)?

FORD ORDER का उपयोग अनुमानों को गलत नहीं कर रहा है, पंक्तियों को हटा दिया गया। तालिका पर आँकड़ों के अद्यतन के लिए अनुमान सटीकता में सुधार हो सकता है।

क्या मुझे यह उम्मीद करनी चाहिए कि मुझे या तो सब-इष्टतम क्वेरी प्रदर्शन स्वीकार करना होगा, या इसे बाज की तरह देखना होगा और अक्सर मैन्युअल रूप से क्वेरी संकेत संपादित करना होगा? या हो सकता है हर संकेत के रूप में अच्छी तरह से शामिल हों? .3s से 2 s एक बड़ी हिट लेने के लिए है।

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

क्या यह स्पष्ट है कि ऑप्टिमाइज़र ने पंक्तियों को हटाने के बाद क्यों उड़ा दिया? उदाहरण के लिए, "हाँ, इसने एक नमूना स्कैन लिया, और क्योंकि मैंने डेटा इतिहास में अधिकांश पंक्तियों को पहले ही संग्रहीत कर लिया था, जिससे नमूना विरल परिणाम प्राप्त करता था, इसलिए इसने क्रमबद्ध हैश ऑपरेशन की आवश्यकता को कम करके आंका"?

आपने समस्या तालिका में पंक्ति संख्या का उल्लेख नहीं किया है, लेकिन यह संभावना है कि विलोपन या तो:

  • आँकड़े अद्यतन को ट्रिगर करने के लिए पर्याप्त पंक्तियाँ नहीं निकालें। यह तब होना चाहिए जब 20% पंक्तियों को संशोधित किया गया है, लेकिन डायनेमिक थ्रेसहोल्ड को सक्षम करने के लिए ट्रेस ध्वज 2371 का उपयोग करने का विकल्प है ।
  • एक आँकड़े अद्यतन को ट्रिगर किया, लेकिन इकट्ठा किया गया नमूना प्रतिनिधि नहीं था। FULLSCAN के साथ मैन्युअल अपडेट चलाकर इसे ठीक करें

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


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

मुझे लगता है कि हां, इसमें ऑप्टिमाइजर्स की पसंद का विकल्प गलत आंकड़ों के साथ सामना करने के लिए होता है, लेकिन इस योजना में शामिल होने के आदेश के कारण मजबूर होना पड़ता है। मुझे पता नहीं है कि FORD ORDER ने आँकड़ों के मूल्यांकन में कोई बदलाव किया है, किसी और को झंकार होगी यदि वे इसके विपरीत कुछ भी जानते हैं। यह भी विचार करने की आवश्यकता है कि क्या आपने OPTIMIZE के लिए जो मूल्य चुना है वह उचित है। हो सकता है कि आंकड़े बिल्कुल ठीक हों, लेकिन आप एक मूल्य के आधार पर एक योजना के लिए मजबूर कर रहे हैं जो प्रतिनिधि नहीं है।
मार्क स्टोरी-स्मिथ

सही। मेरे पास एक ही प्रदर्शन समस्या है जो मापदंडों को ठीक से पार कर रही है जैसे मैंने उन्हें अनुकूलित किया है। एक बार फिर धन्यवाद।
शैनन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.