इंडेक्स कॉलम पर एक बहुत बड़ी टेबल से सेलेक्ट टॉप 1 बहुत धीमा है, लेकिन रिवर्स ऑर्डर ("डीएससी") के साथ नहीं


17

हमारे पास एक बड़ा डेटाबेस है, 1TB के बारे में, एक शक्तिशाली सर्वर पर SQL Server 2014 चला रहा है। कुछ साल तक सब कुछ ठीक चला। लगभग 2 सप्ताह पहले, हमने एक पूर्ण रखरखाव किया, जिसमें शामिल थे: सभी सॉफ़्टवेयर अपडेट स्थापित करें; सभी अनुक्रमित और कॉम्पैक्ट DB फ़ाइलों का पुनर्निर्माण करें। हालाँकि, हमें यह उम्मीद नहीं थी कि निश्चित समय पर DB का CPU उपयोग 100% से बढ़कर 150% हो जाएगा जब वास्तविक भार समान था।

बहुत समस्या निवारण के बाद, हमने इसे बहुत ही सरल क्वेरी के लिए सीमित कर दिया है, लेकिन हमें इसका कोई हल नहीं मिला। प्रश्न अत्यंत सरल है:

select top 1 EventID from EventLog with (nolock) order by EventID

यह हमेशा लगभग 1.5 सेकंड लेता है! हालांकि, "desc" के साथ एक समान क्वेरी हमेशा लगभग 0 एमएस लेती है:

select top 1 EventID from EventLog with (nolock) order by EventID desc

PTable की लगभग 500 मिलियन पंक्तियाँ हैं; EventIDप्राथमिक क्लस्टर्ड इंडेक्स कॉलम (ऑर्डर किया गया) हैASCडेटा प्रकार के बीटिंट (पहचान कॉलम) के साथ ) हैं। शीर्ष पर तालिका में डेटा डालने वाले कई सूत्र हैं (बड़े EventIDs), और नीचे (छोटे EventIDs) से 1 थ्रेड डिलीट डेटा है।

SMSS में, हमने सत्यापित किया कि दो प्रश्न हमेशा एक ही निष्पादन योजना का उपयोग करते हैं:

  • गुच्छेदार सूचकांक स्कैन;

  • अनुमानित और वास्तविक पंक्ति संख्या दोनों 1 हैं;

  • अनुमानों की अनुमानित और वास्तविक संख्या दोनों 1 हैं;

  • अनुमान I / O लागत 8500 है (उच्च होने लगती है)

  • यदि लगातार चलते हैं, तो दोनों के लिए क्वेरी की लागत समान 50% है।

मैंने सूचकांक के आँकड़े अपडेट किए with fullscan, समस्या बनी रही; मैंने फिर से सूचकांक का पुनर्निर्माण किया, और समस्या आधे दिन के लिए चली गई, लेकिन वापस आ गई।

मैंने IO आँकड़ों को चालू किया:

set statistics io on

फिर दो प्रश्नों को लगातार चलाया और निम्नलिखित जानकारी प्राप्त की:

(पहली क्वेरी के लिए, धीमी गति से)

तालिका 'PTable'। स्कैन काउंट 1, लॉजिकल रीडिंग 407670, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।

(दूसरी क्वेरी के लिए, तेज़ एक)

तालिका 'PTable'। स्कैन काउंट 1, लॉजिकल रीड 4, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।

तार्किक रीड्स में भारी अंतर पर ध्यान दें। सूचकांक का उपयोग दोनों मामलों में किया जाता है।

सूचकांक विखंडन थोड़ा समझा सकता है, लेकिन मेरा मानना ​​है कि प्रभाव बहुत छोटा है; और समस्या पहले कभी नहीं हुई। एक अन्य प्रमाण यह है कि क्या मैं एक प्रश्न चलाता हूं:

select * from EventLog with (nolock) where EventID=xxxx   

यहां तक ​​कि अगर मैं xxxx को टेबल के सबसे छोटे ईवेंटिड्स पर सेट करता हूं, तो क्वेरी हमेशा तेज़ होती है।

हमने जाँच की और कोई लॉकिंग / ब्लॉकिंग समस्या नहीं है।

नोट: मैंने सिर्फ ऊपर के मुद्दे को सरल बनाने की कोशिश की। "PTable" वास्तव में "EventLog" है; PIDहैEventID

मुझे NOLOCKसंकेत के बिना एक ही परिणाम परीक्षण मिलता है ।

क्या कोई मदद कर सकता है?

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

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

XML में अधिक विस्तृत क्वेरी निष्पादन योजना निम्नानुसार हैं:

https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob

https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ

मुझे नहीं लगता कि यह सारणी बनाने के लिए मायने रखता है। यह एक पुराना डेटाबेस है और लंबे समय से रखरखाव तक पूरी तरह से ठीक चल रहा है। हमने स्वयं बहुत शोध किया है और इसे मेरे प्रश्न में दी गई जानकारी तक सीमित कर दिया है।

तालिका को सामान्य EventIDरूप से प्राथमिक कुंजी के रूप में स्तंभ के साथ बनाया गया था , जो कि एक identityप्रकार का स्तंभ है bigint। इस समय, मुझे लगता है कि समस्या सूचकांक के विखंडन के साथ है। सूचकांक के पुनर्निर्माण के ठीक बाद, समस्या आधे दिन के लिए चली गई थी; लेकिन यह इतनी जल्दी वापस क्यों आया ...?

जवाबों:


18

क्लस्टर्ड इंडेक्स स्कैन 1923 एमएस लेते हुए, पहली पंक्ति को वापस करने के लिए 423,723 तार्किक रीड दिखाता है:

पागल

यह सूचकांक क्रम में पहली पंक्ति का पता लगाने के लिए बहुत कुछ लगता है।

सबसे अधिक संभावना है कि आपका भूत सफाई कार्य बहुत पीछे चल रहा है, या बंद हो गया है। आपको समय ghost_record_countके साथ क्लस्टर इंडेक्स की जाँच करनी चाहिए sys.dm_db_index_physical_statsऔर परिवर्तनों की निगरानी करनी चाहिए ।

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

एक अन्य प्रदर्शन को प्रभावित करने वाला कारक यह है कि स्टोरेज इंजन के अंदर वर्णित भूत रिकॉर्ड को हटाने के लिए स्कैन स्वयं जिम्मेदार हो जाता है : गहराई में भूत सफाई पॉल रैंडल द्वारा से ।

आपको जांचना चाहिए कि ट्रेस ध्वज 661 (भूत सफाई अक्षम करें) सक्रिय नहीं है।

समाधान

  • आपको लग सकता है कि sp_clean_db_free_space चलाने से राहत मिलती है।
  • एक PAGLOCKसंकेत का उपयोग करने के लिए अनुक्रमणिका के उस छोर से पंक्तियों को हटाने वाली प्रक्रिया को बदलना , मौके पर भूत सफाई को सक्षम करेगा , जो समस्या को भी हल कर सकता है।

यदि भूत सफाई प्रक्रिया पूरी तरह से बंद हो गई है, तो सबसे प्रभावी समाधान सामान्य रूप से SQL सर्वर आवृत्ति को पुनरारंभ करना है। आपको यह भी सुनिश्चित करना चाहिए कि SQL सर्वर नवीनतम संचयी अद्यतनों में से एक चल रहा है। वर्षों में कई भूत सफाई कीड़े हैं।

आपके विशिष्ट मामले में:

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

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