मेरे पास "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-पंक्ति वास्तविक निष्पादन योजना
पहली बात जिस पर मैंने गौर किया, वह यह था कि डिमटाइम टेबल से 60K पंक्तियों को खींचने की बजाय यह उम्मीद करता है कि यह वास्तव में एक बी के साथ 1.6 बिलियन खींच रहा है । मेरी क्वेरी को देखते हुए, मुझे यकीन नहीं है कि यह कैसे वापस खींच रहा है कि कई बार डाइमेट टेबल से पंक्तियाँ। मैं जिस बीटा ऑपरेटर का उपयोग कर रहा हूं वह यह सुनिश्चित करता है कि मैं फैक्ट टेबल में टाइम रिकॉर्ड के आधार पर #mac से सही रिकॉर्ड खींच रहा हूं। हालाँकि, जब मैं WHERE क्लॉज में एक पंक्ति जोड़ता हूं जहां मैं t.TimeValue (या t.TimeID) को एक मान पर फ़िल्टर करता हूं, तो मैं सेकंड के एक मामले में 100,000 पंक्तियों को सफलतापूर्वक अपडेट कर सकता हूं। उस के परिणामस्वरूप, और जैसा कि मैंने शामिल निष्पादन योजनाओं में स्पष्ट किया है, यह स्पष्ट है कि यह मेरी टाइम टेबल समस्या है, लेकिन मुझे यकीन नहीं है कि मैं इस मुद्दे के आसपास काम करने और सटीकता बनाए रखने के लिए कैसे शामिल हो सकता हूं। । कोई विचार?
संदर्भ के लिए, यहां 100 पंक्ति अपडेट के लिए योजना (पंक्ति गणना के साथ) है। आप देख सकते हैं कि यह एक ही सूचकांक को हिट करता है, और अभी भी एक टन पंक्तियों के साथ है, लेकिन कहीं भी एक समस्या के समान परिमाण के पास नहीं है। पंक्ति गणना के साथ 100 पंक्ति निष्पादन :
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 के साथ और एक चयन के रूप में चला सकते हैं , अपडेट के रूप में नहीं और योजना को पोस्ट कर सकते हैं? (खोज स्थान को सरल / द्विभाजित करने की कोशिश कर रहा है)।
t.TimeValue between sma.StartDate and sma.enddate
बहुत अधिक बेकार पंक्तियाँ उत्पन्न हो सकती हैं जो बाद में FactSubscriber के खिलाफ जुड़ने में फ़िल्टर हो जाती हैं और इसलिए अंतिम परिणाम में समाप्त नहीं होती हैं।
sp_updatestatistics
टेबल पर भाग लिया है?