टी-एसक्यूएल क्वेरी मैं अपडेट कर रही पंक्तियों की संख्या के आधार पर पूरी तरह से अलग योजना का उपयोग कर रहा हूं


20

मेरे पास "TOP (X)" क्लॉज वाला SQL UPDATE स्टेटमेंट है, और जिस पंक्ति को मैं मान रहा हूं उसमें लगभग 4 बिलियन पंक्तियां हैं। जब मैं "TOP (10)" का उपयोग करता हूं, तो मुझे एक निष्पादन योजना मिलती है जो लगभग तुरंत निष्पादित होती है, लेकिन जब मैं "TOP (50)" या बड़ा का उपयोग करता हूं, तो क्वेरी कभी नहीं (कम से कम, जब तक मैं इंतजार कर रहा हूं) खत्म नहीं करता है, और यह पूरी तरह से अलग निष्पादन योजना का उपयोग करता है। छोटी क्वेरी इंडेक्स सीक और नेस्टेड लूप की जोड़ी के साथ एक बहुत ही सरल योजना का उपयोग करती है, जहां सटीक एक ही क्वेरी (UPDATE स्टेटमेंट के टॉप क्लॉज में विभिन्न पंक्तियों के साथ) एक ऐसी योजना का उपयोग करती है जिसमें दो अलग-अलग इंडेक्स सॉक्स शामिल होते हैं , एक टेबल स्पूल, समानता, और अन्य जटिलता का एक गुच्छा।

मैंने "विकल्प (USE PLAN ...)" का उपयोग छोटी क्वेरी द्वारा उत्पन्न निष्पादन योजना का उपयोग करने के लिए करने के लिए किया है - जब मैं ऐसा करता हूं, तो मैं कुछ सेकंड में 100,000 पंक्तियों के रूप में अपडेट कर सकता हूं। मुझे पता है कि क्वेरी योजना अच्छी है, लेकिन SQL सर्वर केवल उस योजना को अपने दम पर चुनेगा जब केवल छोटी संख्या में पंक्तियाँ शामिल होती हैं - मेरे अपडेट में किसी भी बड़ी पंक्ति की गणना के परिणामस्वरूप सब-इष्टतम योजना होगी।

मैंने सोचा कि समानता को दोष दिया जा सकता है, इसलिए मैंने MAXDOP 1क्वेरी पर सेट किया, लेकिन कोई असर नहीं हुआ - वह कदम दूर हो गया है, लेकिन खराब विकल्प / प्रदर्शन नहीं है। मैं यह sp_updatestatsसुनिश्चित करने के लिए आज सुबह ही भागा कि इसका कारण नहीं था।

मैंने दो निष्पादन योजनाओं को संलग्न किया है - छोटा भी तेज है। इसके अतिरिक्त, यहाँ प्रश्न में क्वेरी है (यह ध्यान देने योग्य है कि मैंने जो चयन किया है, वह छोटी और बड़ी दोनों पंक्ति के मामलों में त्वरित लगता है):

    update top (10000) FactSubscriberUsage3
               set AccountID = sma.CustomerID
    --select top 50 f.AccountID, sma.CustomerID
      from FactSubscriberUsage3 f
      join dimTime t
        on f.TimeID = t.TimeID
      join #mac sma
        on f.macid = sma.macid
       and t.TimeValue between sma.StartDate and sma.enddate 
     where f.AccountID = 0 --There's a filtered index on the table for this

यहाँ त्वरित योजना है : त्वरित निष्पादन योजना

और यहाँ एक धीमी है : धीमी निष्पादन योजना

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

उन लोगों के लिए जिन्होंने डेटाबेस ऑब्जेक्ट्स का केवल-आँकड़े संस्करण मांगा था : मुझे एहसास भी नहीं था कि आप ऐसा कर सकते हैं, लेकिन यह पूरी तरह से समझ में आता है! मैंने एक आँकड़े-केवल डेटाबेस के लिए स्क्रिप्ट उत्पन्न करने की कोशिश की ताकि अन्य लोग अपने लिए निष्पादन योजनाओं का परीक्षण कर सकें, लेकिन मैं अपने फ़िल्टर किए गए सूचकांक (स्क्रिप्ट में सिंटैक्स त्रुटि, ऐसा लगता है) पर आँकड़े / हिस्टोग्राम उत्पन्न कर सकता हूं, इसलिए मैं हूं भाग्य से बाहर। मैंने फ़िल्टर हटाने की कोशिश की और क्वेरी प्लान करीब थे, लेकिन बिल्कुल वैसा ही नहीं था, और मैं किसी को भी पीछा नहीं छोड़ना चाहता।

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

यहां 10, 100 और 1000 पंक्तियों के लिए सारांश दिया गया है - आप देख सकते हैं कि 1000 पंक्ति क्वेरी रास्ता है, दूसरों के साथ लाइन से बाहर है: कथन सारांश

आप देख सकते हैं कि तीसरी क्वेरी में हास्यास्पद संख्या है, इसलिए यह स्पष्ट रूप से पूरी तरह से कुछ अलग कर रहा है। यहां पंक्ति गणना के साथ अनुमानित निष्पादन योजना है। 1000-पंक्ति अनुमानित निष्पादन योजना: 1000-पंक्ति अनुमानित निष्पादन योजना

और यहाँ निष्पादन योजना के वास्तविक परिणाम हैं (वैसे, "कभी खत्म नहीं होता है", यह पता चला है कि मेरा मतलब है "एक घंटे में खत्म")। 1000-पंक्ति वास्तविक निष्पादन योजना 1000-पंक्ति वास्तविक निष्पादन योजना

पहली बात जिस पर मैंने गौर किया, वह यह था कि डिमटाइम टेबल से 60K पंक्तियों को खींचने की बजाय यह उम्मीद करता है कि यह वास्तव में एक बी के साथ 1.6 बिलियन खींच रहा है । मेरी क्वेरी को देखते हुए, मुझे यकीन नहीं है कि यह कैसे वापस खींच रहा है कि कई बार डाइमेट टेबल से पंक्तियाँ। मैं जिस बीटा ऑपरेटर का उपयोग कर रहा हूं वह यह सुनिश्चित करता है कि मैं फैक्ट टेबल में टाइम रिकॉर्ड के आधार पर #mac से सही रिकॉर्ड खींच रहा हूं। हालाँकि, जब मैं WHERE क्लॉज में एक पंक्ति जोड़ता हूं जहां मैं t.TimeValue (या t.TimeID) को एक मान पर फ़िल्टर करता हूं, तो मैं सेकंड के एक मामले में 100,000 पंक्तियों को सफलतापूर्वक अपडेट कर सकता हूं। उस के परिणामस्वरूप, और जैसा कि मैंने शामिल निष्पादन योजनाओं में स्पष्ट किया है, यह स्पष्ट है कि यह मेरी टाइम टेबल समस्या है, लेकिन मुझे यकीन नहीं है कि मैं इस मुद्दे के आसपास काम करने और सटीकता बनाए रखने के लिए कैसे शामिल हो सकता हूं। । कोई विचार?

संदर्भ के लिए, यहां 100 पंक्ति अपडेट के लिए योजना (पंक्ति गणना के साथ) है। आप देख सकते हैं कि यह एक ही सूचकांक को हिट करता है, और अभी भी एक टन पंक्तियों के साथ है, लेकिन कहीं भी एक समस्या के समान परिमाण के पास नहीं है। पंक्ति गणना के साथ 100 पंक्ति निष्पादन : यहां छवि विवरण दर्ज करें


यह GOTTA सांख्यिकी है। क्या आपने sp_updatestatisticsटेबल पर भाग लिया है?
JNK

@ जेएनके: मैंने शुरू में ऐसा सोचा था, लेकिन पहले से ही बिना किसी बदलाव के sp_updatestats चला चुके हैं। मैंने इसे फिर से चलाया और क्वेरी में शामिल किसी भी इंडेक्स पर आँकड़े अपडेट करने की परवाह नहीं की। हालांकि धन्यवाद!
21 अप्रैल को SqlRyan

दूसरा एक संकीर्ण (प्रति पंक्ति) के बजाय एक विस्तृत (प्रति अनुक्रमणिका) अद्यतन योजना है जो कुछ अतिरिक्त दृश्य जटिलता को स्पष्ट करता है। लेकिन वास्तव में एकमात्र अंतर है ऑर्डर from #mac sma join f on f.macid = sma.macid join dimTime t on f.TimeID = t.TimeID and t.TimeValue between sma.StartDate and sma.enddateबनामfrom #mac join t on t.TimeValue between sma.StartDate and sma.enddate join f on f.TimeID = t.TimeID and f.macid = sma.macid
मार्टिन स्मिथ

यहां कुछ ठीक दिखाई नहीं देता। यहां तक ​​कि महंगी क्वेरी योजना को पंक्तियों को वृद्धिशील रूप से उत्पन्न करना चाहिए। ए TOP 50को अभी भी जल्दी से निष्पादित करना चाहिए। क्या आप XML प्लान अपलोड कर सकते हैं? मुझे पंक्ति गणना पर ध्यान देने की आवश्यकता है। क्या आप TOP 50अधिकतम 1 के साथ और एक चयन के रूप में चला सकते हैं , अपडेट के रूप में नहीं और योजना को पोस्ट कर सकते हैं? (खोज स्थान को सरल / द्विभाजित करने की कोशिश कर रहा है)।
usr

@usr पर जुड़ना t.TimeValue between sma.StartDate and sma.enddate बहुत अधिक बेकार पंक्तियाँ उत्पन्न हो सकती हैं जो बाद में FactSubscriber के खिलाफ जुड़ने में फ़िल्टर हो जाती हैं और इसलिए अंतिम परिणाम में समाप्त नहीं होती हैं।
मार्टिन स्मिथ

जवाबों:


3

मंद समय पर सूचकांक बदल रहा है। तेज योजना _dta इंडेक्स का उपयोग कर रही है। सबसे पहले, सुनिश्चित करें कि sys.indexes में काल्पनिक सूचकांक के रूप में चिह्नित नहीं किया गया है।

यह सोचकर कि आप केवल स्टार्ट / एंड डेट्स की आपूर्ति करने के बजाय #mac टेबल को फ़िल्टर करने के लिए कुछ पैरामीटराइज़ेशन को दरकिनार कर सकते हैं जैसे कि @StartDate और @enddate के बीच इस समय t.TimeValue। उस टेम्‍परेचर टेबल से छुटकारा पाएं।


Dta उपसर्ग सूचकांक केवल ऐसा लगता है जैसे नाम को अनुकूलित किए बिना DTA अनुशंसा का पालन करके बनाया गया था। हाइपोथेटिकल इंडेक्स वास्तविक निष्पादन योजनाओं में दिखाई नहीं दे सकते हैं (और कुछ अनिर्दिष्ट आदेशों के बिना अनुमान नहीं है)। यकीन नहीं होता कि आपका दूसरा सुझाव कैसे काम करेगा। t.TimeValue between sma.StartDate and sma.enddateसहसंबद्ध है इसलिए #tempतालिका में प्रत्येक पंक्ति के लिए बदल सकते हैं । ओपी इसकी जगह क्या लेगा?
मार्टिन स्मिथ

पर्याप्त रूप से, मैंने अस्थायी तालिका पर पर्याप्त ध्यान नहीं दिया।
william_a_dba

1
हालांकि, काल्पनिक सूचकांक वास्तव में एक निष्पादन योजना बना सकते हैं। यदि यह काल्पनिक है, तो इसे गिरा दिया जाना चाहिए और फिर से बनाया जाना चाहिए। blogs.technet.com/b/anurag_sharma/archive/2008/04/15/…
william_a_dba

DTA के पूरा होने से पहले / जमा नहीं होने पर हाइपोथेटिकल इंडेक्स को छोड़ दिया जाता है। DTA के साथ कोई भी हिचकी होने पर आपको उन्हें मैन्युअल रूप से साफ़ करना होगा।
william_a_dba

1
@william_a_dba - आह मैं देख रहा हूं कि अब आपका क्या मतलब है (आपके लिंक को पढ़ने के बाद)। क्वेरी कभी खत्म नहीं होती है यह लगातार फिर से हो सकता है। दिलचस्प!
मार्टिन स्मिथ

1

योजना में पंक्ति गणना के बारे में अधिक जानकारी के बिना, मेरी प्रारंभिक सिफारिश क्वेरी में सही जॉइन ऑर्डर के लिए व्यवस्था करने और उपयोग करने के लिए बाध्य करने के लिए है OPTION (FORCE ORDER)। पहली योजना के सम्मिलित आदेश को लागू करें।

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