क्या उत्सुक स्पूल ऑपरेटर एक क्लस्टर किए गए कॉलमस्टोर से इस डिलीट के लिए उपयोगी है?


28

मैं क्लस्टर किए गए कॉलमस्टोर इंडेक्स से डेटा हटाने का परीक्षण कर रहा हूं।

मैंने देखा कि निष्पादन योजना में एक बड़ा उत्सुक स्पूल ऑपरेटर है:

यहाँ छवि विवरण दर्ज करें

यह निम्नलिखित विशेषताओं के साथ पूरा होता है:

  • 60 मिलियन पंक्तियों को हटाया गया
  • 1.9 GiB TempDB का उपयोग किया
  • 14 मिनट का निष्पादन समय
  • सीरियल की योजना
  • स्पूल पर 1 रिबंड
  • स्कैन के लिए अनुमानित लागत: 364.821

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

यहाँ छवि विवरण दर्ज करें

स्कैन की अनुमानित लागत: 56.901

(यह एक अनुमानित योजना है, लेकिन टिप्पणियों में संख्या सही है।)

दिलचस्प है, स्पूल फिर से गायब हो जाता है अगर मैं निम्नलिखित को चलाकर डेल्टा स्टोर्स को फ्लश करता हूं:

ALTER INDEX IX_Clustered ON Fact.RecordedMetricsDetail REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

स्पूल केवल तब पेश किया जाता है जब डेल्टा स्टोर में पृष्ठों की कुछ सीमा से अधिक होती है।

डेल्टा स्टोरों के आकार की जाँच करने के लिए, मैं तालिका के लिए पंक्ति के पन्नों की जाँच करने के लिए निम्नलिखित प्रश्न चला रहा हूँ:

SELECT  
  SUM([in_row_used_page_count]) AS in_row_used_pages,
  SUM(in_row_data_page_count) AS in_row_data_pages
FROM sys.[dm_db_partition_stats] as pstats
JOIN sys.partitions AS p
ON pstats.partition_id = p.partition_id
WHERE p.[object_id] = OBJECT_ID('Fact.RecordedMetricsDetail');

क्या पहली योजना में स्पूल इटरेटर का कोई प्रशंसनीय लाभ है? मुझे यह मानकर चलना चाहिए कि यह एक प्रदर्शन वृद्धि के रूप में है और हैलोवीन सुरक्षा के लिए नहीं है क्योंकि इसकी उपस्थिति सुसंगत नहीं है।

मैं 2016 के CTP 3.1 पर इसका परीक्षण कर रहा हूं, लेकिन मुझे 2014 SP1 CU3 पर समान व्यवहार दिखाई देता है।

मैंने एक स्क्रिप्ट पोस्ट की है जो स्कीमा और डेटा जेनरेट करती है और आपको समस्या के प्रदर्शन के माध्यम से चलता है

यह प्रश्न इस बिंदु पर ऑप्टिमाइज़र के व्यवहार के बारे में ज्यादातर उत्सुकता से बाहर है क्योंकि मेरे पास इस मुद्दे के लिए एक वर्कअराउंड है जो प्रश्न को प्रेरित करता है (एक बड़ा स्पूल भरा TempDB)। मैं अब विभाजन स्विचिंग का उपयोग करके हटा रहा हूं।


2
अगर मैं कोशिश करूं OPTION (QUERYRULEOFF EnforceHPandAccCard)तो स्पूल गायब हो जाता है। मुझे लगता है कि एचपी "हेलोवीन संरक्षण" हो सकता है। हालाँकि तब एक USE PLANसंकेत के साथ उस योजना का उपयोग करने की कोशिश विफल रहती है (जैसा कि OPTIMIZE FOR वर्कअराउंड से भी योजना का उपयोग करने की कोशिश करता है)
मार्टिन स्मिथ

धन्यवाद @MartinSmith किसी भी विचार क्या AccCardहोगा? आरोही कॉलम कार्डिनैलिटी कार्डिनैलिटी शायद?
जेम्स एल

1
@JamesLupolt नहीं मैं कुछ भी विशेष रूप से मुझे समझाने के साथ नहीं आ सकता है। हो सकता है कि Acc Acculateulate या Access हो?
मार्टिन स्मिथ

जवाबों:


22

क्या पहली योजना में स्पूल इटरेटर का कोई प्रशंसनीय लाभ है?

यह इस बात पर निर्भर करता है कि आप "प्रशंसनीय" के रूप में क्या मानते हैं, लेकिन लागत मॉडल के अनुसार उत्तर हां है। बेशक यह सच है, क्योंकि ऑप्टिमाइज़र हमेशा सबसे सस्ती योजना चुनता है जिसे वह पाता है।

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

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE);

इस योजना की अनुमानित लागत 771,734 इकाई है :

मूल योजना

लागत लगभग सभी क्लस्टर्ड इंडेक्स डिलीट से जुड़ी है, क्योंकि विलोपन के परिणामस्वरूप यादृच्छिक I / O का एक बड़ा सौदा होने की उम्मीद है। यह केवल सामान्य तर्क है जो सभी डेटा संशोधनों पर लागू होता है। उदाहरण के लिए, बी-ट्री इंडेक्स में संशोधनों का एक अनियंत्रित सेट माना जाता है कि एक उच्च I / O लागत के साथ बड़े पैमाने पर यादृच्छिक I / O में परिणाम होता है।

डेटा-बदलने की योजना में क्रमबद्ध रूप से इन पंक्तियों को क्रमबद्ध रूप से प्रस्तुत करने की सुविधा हो सकती है, जो इन लागत कारणों से क्रमिक पहुँच को बढ़ावा देगी। इस मामले में प्रभाव समाप्त हो जाता है क्योंकि तालिका का विभाजन होता है। बहुत विभाजन, वास्तव में; आपकी स्क्रिप्ट उनमें से 15,000 का निर्माण करती है। बहुत विभाजन तालिका में रैंडम अपडेट की विशेष रूप से उच्च लागत होती है क्योंकि विभाजन (पंक्तियों) को मध्य-धारा में बदलने की कीमत के साथ-साथ उच्च लागत भी दी जाती है।

विचार करने के लिए अंतिम प्रमुख कारक यह है कि ऊपर दी गई सरल अद्यतन क्वेरी (जहां 'अपडेट' का अर्थ है किसी भी डेटा-बदलने वाला ऑपरेशन, जिसमें एक डिलीट भी शामिल है) "रूसेट शेयरिंग" नामक एक अनुकूलन के लिए अर्हता प्राप्त करता है, जहां स्कैनिंग और दोनों के लिए एक ही आंतरिक रोसेट का उपयोग किया जाता है। तालिका को अद्यतन करना। निष्पादन योजना अभी भी दो अलग-अलग ऑपरेटरों को दिखाती है, लेकिन फिर भी, केवल एक ही पंक्तियों का उपयोग किया जाता है।

मैं इसका उल्लेख करता हूं क्योंकि इस अनुकूलन को लागू करने में सक्षम होने का मतलब है कि ऑप्टिमाइज़र एक कोड पथ लेता है जो बस यादृच्छिक I / O की लागत को कम करने के लिए स्पष्ट रूप से छंटाई के संभावित लाभों पर विचार नहीं करता है । जहां टेबल एक बी-ट्री है, यह समझ में आता है, क्योंकि संरचना स्वाभाविक रूप से आदेशित होती है, इसलिए पंक्तियों को साझा करने से स्वचालित रूप से सभी संभावित लाभ मिलते हैं।

महत्वपूर्ण परिणाम यह है कि अद्यतन ऑपरेटर के लिए लागत तर्क इस आदेश लाभ (क्रमिक I / O या अन्य अनुकूलन को बढ़ावा देने) पर विचार नहीं करता है जहां अंतर्निहित ऑब्जेक्ट स्तंभ की दुकान है। इसका कारण यह है कि कॉलम स्टोर संशोधनों को इन-प्लेस नहीं किया जाता है; वे एक डेल्टा स्टोर का उपयोग करते हैं। इसलिए लागत मॉडल बी-पेड़ों बनाम कॉलमस्टोर्स पर साझा-पंक्तियों के अपडेट के बीच अंतर को दर्शा रहा है।

फिर भी, एक (बहुत!) विभाजन किए गए स्तंभ की विशेष स्थिति में, संरक्षित ऑर्डर करने के लिए अभी भी एक लाभ हो सकता है, जिसमें एक विभाजन से पहले सभी अपडेट करने से पहले एक I / O के दृष्टिकोण से लाभप्रद हो सकता है ।

यहां कॉलम स्टोर के लिए मानक लागत तर्क का पुन: उपयोग किया जाता है, इसलिए एक योजना जो विभाजन आदेश को संरक्षित करती है (हालांकि प्रत्येक विभाजन के भीतर आदेश नहीं) कम लागत वाली है। अपडेट ऑपरेटर को सॉर्ट किए गए इनपुट की आवश्यकता के लिए हम इसे अनकॉम्लेटेड ट्रेस ध्वज 2332 का उपयोग करके परीक्षण क्वेरी पर देख सकते हैं। यह DMLRequestSortसंपत्ति को अद्यतन करने के लिए सेट करता है , और ऑप्टिमाइज़र को एक योजना बनाने के लिए मजबूर करता है जो अगले विभाजन के लिए जाने से पहले एक विभाजन के लिए सभी पंक्तियाँ प्रदान करता है:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332);

इस योजना की अनुमानित लागत बहुत कम है, 52.5174 इकाइयों पर:

DMLRequestSort = सच्ची योजना

लागत में यह कमी अपडेट में कम अनुमानित I / O लागत के कारण है। प्रस्तुत स्पूल कोई उपयोगी कार्य नहीं करता है, सिवाय इसके कि यह विभाजन के क्रम में आउटपुट की गारंटी दे सकता है, जैसा कि अपडेट के लिए आवश्यक है DMLRequestSort = true(कॉलम स्टोर इंडेक्स का सीरियल स्कैन इस गारंटी को प्रदान नहीं कर सकता है)। स्पूल की लागत को अपेक्षाकृत कम माना जाता है, विशेष रूप से अद्यतन में लागत में (शायद अवास्तविक) कमी के साथ तुलना में।

अद्यतन ऑपरेटर को आदेशित इनपुट की आवश्यकता के बारे में निर्णय क्वेरी अनुकूलन में बहुत जल्दी किया जाता है। इस निर्णय में उपयोग किए गए अनुमानों को कभी भी प्रलेखित नहीं किया गया है, लेकिन परीक्षण और त्रुटि के माध्यम से निर्धारित किया जा सकता है। ऐसा लगता है कि किसी भी डेल्टा स्टोर का आकार इस निर्णय के लिए एक इनपुट है। एक बार बनाने के बाद, विकल्प क्वेरी संकलन के लिए स्थायी है। कोई USE PLANसंकेत सफल नहीं होगा: योजना के लक्ष्य ने या तो अपडेट के लिए इनपुट का आदेश दिया है, या यह नहीं करता है।

कार्डिनिटी अनुमान को कृत्रिम रूप से सीमित किए बिना इस क्वेरी के लिए कम लागत वाली योजना प्राप्त करने का एक और तरीका है। स्पूल से बचने के लिए पर्याप्त रूप से कम अनुमान संभवतः DMLRequestSort के परिणामस्वरूप गलत होगा, जिसके परिणामस्वरूप अपेक्षित यादृच्छिक I / O के कारण बहुत अधिक अनुमानित योजना लागत होती है। 2332 (DMLRequestSort = true) के साथ संयोजन में ट्रेस ध्वज 8649 (समानांतर योजना) का उपयोग करने के लिए एक विकल्प है:

DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332, QUERYTRACEON 8649);

प्रति-बैच बैच-मोड समानांतर स्कैन और ऑर्डर-प्रोटेक्शन (मर्जिंग) इकट्ठा करने की योजना में यह परिणाम प्राप्त होता है:

डिलीट करने का आदेश दिया

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

कई, अपेक्षाकृत नई, सुविधाओं को मिलाकर, विशेष रूप से उनकी सीमाओं के पास, खराब निष्पादन योजनाओं को प्राप्त करने का एक शानदार तरीका है। ऑप्टिमाइज़र समर्थन की गहराई समय के साथ बेहतर होती जाती है, लेकिन कॉलम स्टोर के 15,000 विभाजनों का उपयोग करने की संभावना हमेशा दिलचस्प समय में रहती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.