फ़िल्टर्ड (गैर-शून्य मान) अनुक्रमित के साथ अनुक्रमणिका को प्रतिस्थापित करने का क्या प्रभाव है?


10

हमारा प्रोजेक्ट बहुत बड़ा, बहुत जटिल डेटाबेस चलाता है। इसलिए लगभग एक महीने पहले, हमने देखा कि अशक्त मानों वाले अनुक्रमित स्तंभों द्वारा उपयोग किया जाने वाला स्थान बहुत बड़ा हो रहा था। उस पर प्रतिक्रिया के रूप में, मैंने स्क्रिप्ट के रूप में लिखा था जो गतिशील रूप से सभी सिंगल-कॉलम इंडेक्स के माध्यम से खोज करेगा जिसमें 1% से अधिक शून्य मान होंगे, फिर उन इंडेक्स को फ़िल्टर्ड इंडेक्स के रूप में इस शर्त पर ड्रॉप और रीक्रिएट करें कि मान शून्य नहीं था। यह पूरे डेटाबेस में सैकड़ों अनुक्रमितों को गिराएगा और फिर से बनाएगा और आम तौर पर पूरे डीबी द्वारा उपयोग किए जाने वाले अंतरिक्ष के लगभग 15% को मुक्त करेगा।

अब मेरे पास इस बारे में दो प्रश्न हैं:

ए) इस फैशन में फ़िल्टर्ड इंडेक्स का उपयोग करने के डाउनसाइड क्या हैं? मैं यह मानूंगा कि यह केवल प्रदर्शन में सुधार करेगा, लेकिन क्या कोई प्रदर्शन जोखिम शामिल हैं?

बी) हमें त्रुटियां मिलीं ( 'इंडेक्स को ड्रॉप नहीं कर सकता एक्सवाईजेड बीयूज यह मौजूद नहीं है या आपके पास अनुमति नहीं है' ) इंडेक्स को छोड़ने और पुन: बनाने पर, भले ही बाद में जांच की गई हो, सब कुछ बिल्कुल उम्मीद के मुताबिक चला गया था। ये केसे हो सकता हे?

किसी भी मदद के लिए धन्यवाद!

संपादित करें: @Thomas Kejser के जवाब में

हाय और धन्यवाद, लेकिन यह पता चला है कि यह एक आपदा थी। उस समय हमें कई चीजें समझ में नहीं आईं:

  1. एक क्वेरी के दौरान, SQLOS यह निर्धारित करने से पहले सूचकांक योजना बनाता है कि यह तालिका कॉलम में शामिल होने के लिए NULL मान का उपयोग नहीं कर सकता है। IE, आपको वास्तव में क्वेरी में उपयोग किए गए प्रत्येक और हर फ़िल्टर किए गए इंडेक्स के लिए सूचकांक को फिट करने वाले WHERE क्लॉज़ की आवश्यकता है, या इंडेक्स का उपयोग बिल्कुल भी नहीं किया जाएगा।
  2. अनुक्रमित करना और बनाना और फिर से अपने आँकड़ों को फिर से अपडेट करना, फिर भी अद्यतन योजनाओं का उत्पादन करने के लिए पर्याप्त नहीं हो सकता है, जो हमने माना था कि वे करेंगे। ऐसा लगता है कि कुछ मामलों में केवल एक उच्च पर्याप्त कार्यभार SQL सर्वर को योजनाओं को आश्वस्त करने के लिए मजबूर करेगा।
  3. निष्पादन योजनाकार की कार्यक्षमता के लिए कुछ एक्सोटिक्स हैं जो अकेले सामान्य ज्ञान और तर्क द्वारा निर्धारित करना मुश्किल है। विभिन्न प्रश्नों के हजारों-कोड-पीछे-भिन्न रूपों के साथ भी, प्रतीत होता है कि बेकार सूचकांक कुछ आंकड़ों और क्वेरी योजनाओं में मदद कर सकते हैं जो महत्वपूर्ण प्रश्नों में उपयोग किए जा रहे हैं।

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


आप अपनी अनुक्रमण रणनीति की भी पुनः जांच कर सकते हैं। यदि आपके पास सैकड़ों एकल फ़ील्ड इंडेक्स हैं तो यह संभवतः इष्टतम नहीं है।
जेएनके

इनकी आवश्यकता इस तथ्य से आती है कि डेटाबेस आंशिक रूप से किसी अन्य सिस्टम से विरासत में मिला है। डिफ़ॉल्ट रूप से, हमारे पास कुछ सार तालिकाओं, और कई सार स्तंभ हैं जिनका उपयोग बिल्कुल भी नहीं किया जा सकता है, जो कि इनमें से अधिकांश बड़े पैमाने पर अनुक्रमित पूर्ण मानों का उत्पादन करता है। सिंगल-फील्ड इंडेक्स के लिए, वे आधार आवश्यकता से बनाए जाते हैं जो प्रत्येक विदेशी कुंजी को अनुक्रमित किया जाना चाहिए, और उनमें से कई इन स्तंभों में होते हैं जिनमें ज्यादातर या केवल NULL मान होते हैं।
कहे

जवाबों:


8

बहुत दिलचस्प दृष्टिकोण। रचनात्मकता के लिए मेरा उत्थान।

जब से आपने अंतरिक्ष को पुनः प्राप्त किया, मुझे लगता है कि मूल सूचकांक अब नहीं हैं? फ़िल्टर किए गए अनुक्रमित के डाउनसाइड फिर निम्न हैं:

  • उनमें से बहुत से ऑप्टिमाइज़र के खोज स्थान को बहुत बड़ा होने का कारण हो सकता है, जिससे ऑप्टिमाइज़र बार के रूप में खराब क्वेरी योजनाओं के लिए अग्रणी होता है
  • ऐसी कई स्थितियां हैं जहां एक फ़िल्टर किए गए सूचकांक पर भी विचार नहीं किया जाएगा, भले ही गैर-फ़िल्टर किए गए समकक्ष होंगे। विशेष रूप से, यह तब हो सकता है जब आप अनुक्रमित स्तंभ पर एक हैश ज्वाइन करते हैं या यदि आप स्तंभ द्वारा (फ़िल्टर के बिना) आदेश देने का प्रयास करते हैं
  • फ़िल्टर किए गए अनुक्रमितों के साथ क्वेरी पैरामीटराइज़ेशन काम नहीं करता है (देखें: http://www.sqlservercentral.com/blogs/practicalsqldba/2013/04/08/sql-server-part-9-filtered-index-a-new-way- प्रदर्शन-सुधार-सुधार / )

व्यावहारिक रूप से, इसका मतलब है कि आपको फ़िल्टर्ड इंडेक्स के साथ बेहद सावधान रहना होगा क्योंकि वे अक्सर भयानक क्वेरी योजनाओं के परिणामस्वरूप होंगे। मैं उन्हें बेकार कहने के लिए इतनी दूर नहीं जाऊंगा, लेकिन मैं उन्हें पारंपरिक अनुक्रमित के अतिरिक्त के रूप में देखता हूं, न कि प्रतिस्थापन के रूप में (जैसा कि आप करने की कोशिश कर रहे हैं)।


"क्वेरी पैरामीटराइज़ेशन फ़िल्टर्ड इंडेक्स के साथ काम नहीं करता है"। यह शायद विकल्प (recompile) के साथ तय किया जा सकता है
MichaelD

2

थॉमस केसर ने इस विषय का अच्छी तरह से उत्तर दिया

मैंने सिर्फ 2 सेंट जोड़ने के बारे में सोचा था।

मैंने कुछ फ़िल्टर किए गए अनुक्रमणिकाओं को केवल उपयोग किया जा रहा है (निष्पादन योजना में दिखाया गया है) देखा है जब आप सटीक रूप से फ़िल्टर किए गए अनुक्रमणिका में अपनी क्वेरी में जहाँ क्लॉज़ से मेल खाते हैं।

क्या आपने अनुक्रमित विचारों का उपयोग करने की कोशिश की है ? विरल स्तंभ ?

मेरा मानना ​​है कि जहां तक ​​आपके पास केवल आंतरिक जोड़ हैं, आप एक अनुक्रमित दृश्य बना सकते हैं जिसमें आपके फ़िल्टर किए गए अनुक्रमित के खंड (ओं) से युक्त है और फिर आप इसके बजाय दृश्य का उपयोग कर सकते हैं।

एक से अधिक दृश्य हो सकते हैं। लेकिन नॉन क्लस्टर्ड इंडेक्स के साथ भी, बहुत से आपके लेखन को धीमा कर देंगे।

मेरे अनुभव में आपको पढ़ने में अच्छा लाभ होगा लेकिन आपको विशेष रूप से लिखने (आवेषण और अद्यतन) की निगरानी करनी होगी, यदि तालिका प्रतिकृति में शामिल हो।

हालाँकि, जैसा कि मैं समझता हूं कि आपकी मुख्य चिंता the null valuesयह है कि मैं आपको अपनी अनुक्रमणिका में स्पार्क कॉलम का सुझाव दूंगा

विशेष रूप से फ़िल्टर किए गए अनुक्रमित के लिए स्पार्स कॉलम उपयुक्त हैं

जैसा कि मैंने विरल स्तंभों का विज्ञापन किया है, मुझे अच्छा नहीं लगेगा अगर मैं आपको इसकी सीमाओं के बारे में नहीं बताता:

विरल स्तंभों के साथ तालिकाएँ डिज़ाइन करते समय, ध्यान रखें कि जब एक पंक्ति को अद्यतन किया जा रहा हो तो तालिका में प्रत्येक गैर-शून्य विरल स्तंभ के लिए अतिरिक्त 2 बाइट्स की आवश्यकता होती है।

इसके परिणामस्वरूप

अतिरिक्त मेमोरी आवश्यकता, अपडेट अप्रत्याशित रूप से 576 त्रुटि के साथ विफल हो सकते हैं जब इस मेमोरी ओवरहेड सहित कुल पंक्ति का आकार 8019 से अधिक हो,

और किसी भी कॉलम को पंक्ति से धकेला नहीं जा सकता है।

उस तालिका के> उदाहरण पर विचार करें जिसमें टाइप बिगिंट के 600 विरल स्तंभ हैं।

यदि 571 गैर-शून्य कॉलम हैं, तो डिस्क पर कुल आकार 571 * 12 = 6852 बाइट्स है। अतिरिक्त पंक्ति उपरि और विरल स्तंभ शीर्ष लेख शामिल करने के बाद, यह लगभग 6895 बाइट्स तक बढ़ जाता है। पृष्ठ पर अभी भी डिस्क पर लगभग 1124 बाइट उपलब्ध हैं। इससे यह धारणा दी जा सकती है कि अतिरिक्त कॉलम सफलतापूर्वक अपडेट किए जा सकते हैं। हालाँकि, अद्यतन के दौरान, स्मृति में अतिरिक्त ओवरहेड है जो 2 * (गैर-शून्य स्पार्स कॉलम की संख्या) है। इस उदाहरण में, अतिरिक्त ओवरहेड सहित - 2 * 571 = 1142 बाइट्स - डिस्क पर पंक्ति का आकार 8037 बाइट्स तक बढ़ाता है। यह आकार 8019 बाइट्स के अधिकतम अनुमत आकार से अधिक है। चूँकि सभी कॉलम निश्चित लंबाई के डेटा प्रकार हैं, इसलिए उन्हें पंक्ति से बाहर नहीं किया जा सकता है। परिणामस्वरूप, 576 त्रुटि के साथ अद्यतन विफल रहता है।

ऊपर दिए गए लिंक पर अधिक जानकारी, हालांकि मैं इस चेतावनी को भी यहां पोस्ट करना पसंद करता हूं:

एक स्तंभ को विरल से nonsparse या nonsparse से विरल में बदलने से स्तंभ के संग्रहण स्वरूप को बदलने की आवश्यकता होती है।

SQL सर्वर डेटाबेस इंजन इस परिवर्तन को पूरा करने के लिए निम्न प्रक्रिया का उपयोग करता है:

1 - नए भंडारण आकार और प्रारूप में तालिका में एक नया कॉलम जोड़ता है।

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

3 - टेबल स्कीमा से पुराने कॉलम को हटाता है।

4 - तालिका को पुनर्निर्मित करता है (यदि कोई क्लस्टर इंडेक्स नहीं है) या पुराने कॉलम द्वारा उपयोग किए गए स्थान को पुनः प्राप्त करने के लिए क्लस्टर इंडेक्स का पुनर्निर्माण करता है।


1
नमस्ते। थोड़ी देर के लिए, लेकिन हाँ, जबकि हमने इस विषय में वर्णित दृष्टिकोण को बहुत पहले छोड़ दिया था, हमने हाल ही में अधिक चयनात्मक दृष्टिकोण के साथ इस पर वापस लौटे। मूल रूप से, हमने प्रति तालिका के आधार पर सूचकांक की पुष्टि करने के लिए सांख्यिकी उपयोग और व्यापार मॉडल को देखा। फिर सामान्य के पक्ष में एक नया फ़िल्टर किए गए सूचकांक को जोड़कर इसका परीक्षण किया, और कुछ हफ्तों में देखने के लिए जाँच की जो समाप्त हो गई थी। यह पुष्टि करने के बाद कि नई योजनाओं में केवल फ़िल्टर किए गए इंडेक्स का उपयोग किया गया था, हमने सामान्य नॉनफिल्ड वाले को गिरा दिया।
कहन

1
इसके अलावा, हमने विरल प्रकार के कुछ स्तंभों को बदल दिया। हालांकि इसके साथ समस्या यह है कि जैसा कि आप MSDN से देखेंगे, एक स्तंभ प्रकार को विरल रूप से बदलकर मूल रूप से पूरे संकुल सूचकांक को फिर से बनाने के लिए मजबूर करता है। इसे बड़े, जटिल तालिकाओं के बजाय भारी बनाना। इसलिए हमने बाधाओं और तालिका का नाम बदल दिया, एक ही मॉडल और मूल नाम के साथ एक नया निर्माण किया लेकिन विरल स्तंभों के साथ, और फिर डेटा को नई तालिका में उपयुक्त बैचों में स्थानांतरित कर दिया। फिर एक बार जाँच की कि सब कुछ ठीक था और सभी अनुक्रमित और एफके फिर से जगह में थे, पुरानी तालिकाओं को गिरा दिया।
कहन

1
इसके अलावा, कुछ मामलों में पेज कम्प्रेशन का उपयोग करना बेहतर था, इसलिए हमने इसके बजाय ऐसा करना समाप्त कर दिया। यह तब से भी आसान है क्योंकि आप DROP_EXISTING = ON के साथ केवल मौजूदा क्लस्टर इंडेक्स बना सकते हैं, इसे स्पार्स रूट पर जाने की तुलना में कहीं अधिक तेज़ बनाते हैं। विशेष रूप से चूंकि यह अनुक्रमणिका और एफके के पुन: प्रबंधन की पूरी परेशानी से बचा जाता है।
कहन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.