जब पहले से तेज़ SQL क्वेरी धीमी गति से चलने लगती है, तो मुझे समस्या का स्रोत कहां दिखता है?


36

पृष्ठभूमि

मेरे पास SQL ​​Server 2008 R2 के खिलाफ चलने वाली एक क्वेरी है जो 12 अलग-अलग "टेबल" के साथ मिलती है और / या लेफ्ट-जॉइन करती है। डेटाबेस 50 मिलियन पंक्तियों और लगभग 300 विभिन्न तालिकाओं के साथ कई तालिकाओं के साथ काफी बड़ा है। यह एक बड़ी-ईश कंपनी के लिए है जिसके पूरे देश में 10 वेयरहाउस हैं। सभी वेयरहाउस डेटाबेस पर पढ़ते हैं और लिखते हैं। तो यह बहुत बड़ा और बहुत व्यस्त है।

जिस क्वेरी से मुझे परेशानी हो रही है वह कुछ इस तरह दिखती है:

select t1.something, t2.something, etc.
from Table1 t1
    inner join Table2 t2 on t1.id = t2.t1id
    left outer join (select * from table 3) t3 on t3.t1id = t1.t1id
    [etc]...
where t1.something = 123

ध्यान दें कि एक जोड़ गैर-सहसंबद्ध उप-क्वेरी पर है।

समस्या यह है कि आज सुबह से, बिना किसी बदलाव के (जो कि मैं या मेरी टीम पर कोई भी जानता है) सिस्टम को, जिस क्वेरी को चलाने के लिए आमतौर पर लगभग 2 मिनट लगते हैं, उसे चलाने में एक घंटा और एक घंटा लगने लगा - जब यह बिल्कुल भागे। डेटाबेस के बाकी सिर्फ ठीक साथ गुनगुना रहा है। मैंने इस क्वेरी को स्प्रो से बाहर निकाल दिया है जो आमतौर पर इसमें चलता है और मैंने इसे एसएसएमएस w / हार्ड-कोडेड पैरामीटर चर में उसी धीमेपन के साथ चलाया है।

विचित्रता यह है कि जब मैं गैर-सहसंबद्ध उप-क्वेरी लेता हूं और इसे एक अस्थायी तालिका में फेंक देता हूं, और फिर उप-क्वेरी के बजाय इसका उपयोग करता हूं, तो क्वेरी ठीक चलती है। इसके अलावा (यह मेरे लिए सबसे अजीब है) अगर मैं क्वेरी के अंत में कोड का यह टुकड़ा जोड़ता हूं, तो क्वेरी बहुत बढ़िया चलती है:

and t.name like '%'

मैंने इन छोटे प्रयोगों से (शायद गलत तरीके से) निष्कर्ष निकाला है कि धीमे-धीमे का कारण यह है कि SQL की कैश्ड निष्पादन योजना कैसे सेट की जाती है - जब क्वेरी थोड़ी अलग होती है, तो उसे एक नई निष्पादन योजना बनानी होती है।

मेरा प्रश्न यह है: जब एक क्वेरी जो तेजी से चलती थी, वह अचानक रात के बीच में धीरे-धीरे चलने लगती है और इस एक क्वेरी के अलावा और कुछ भी प्रभावित नहीं होता है, मैं इसे कैसे परेशान करूं और इसे भविष्य में होने से कैसे बचाऊं ? मुझे कैसे पता चलेगा कि SQL इसे इतना धीमा बनाने के लिए आंतरिक रूप से क्या कर रहा है (यदि खराब क्वेरी चली, तो मैं इसकी निष्पादन योजना प्राप्त कर सकता हूं लेकिन यह नहीं चलेगा - शायद अपेक्षित निष्पादन योजना मुझे कुछ दे सकती है?)। यदि यह समस्या निष्पादन योजना के साथ है, तो मैं यह सोचकर एसक्यूएल कैसे रख सकता हूं कि वास्तव में भद्दा निष्पादन योजना एक अच्छा विचार है?

इसके अलावा, यह पैरामीटर सूँघने की समस्या नहीं है। मैंने देखा है कि पहले, और यह नहीं है, क्योंकि जब भी मैं SSMS में varaibles को हार्ड-कोड करता हूं, तब भी मुझे धीमा प्रदर्शन मिलता है।


क्या आप यहाँ क्वेरी प्लान (धीमे से) साझा कर सकते हैं: brentozar.com/pastetheplan
MJH

जवाबों:


31

जब एक क्वेरी जो तेजी से चलती थी, वह अचानक रात के बीच में धीरे-धीरे चलने लगती है और इस एक क्वेरी के अलावा और कुछ भी प्रभावित नहीं होता है, मैं इसे कैसे परेशान करूं ...?

आप जांच शुरू कर सकते हैं कि क्या निष्पादन योजना अभी भी कैश में है। जाँच करें sys.dm_exec_query_stats, sys.dm_exec_procedure_statsऔर sys.dm_exec_cached_plans। यदि खराब निष्पादन योजना अभी भी कैश की गई है तो आप इसका विश्लेषण कर सकते हैं, और आप निष्पादन आँकड़े भी देख सकते हैं। निष्पादन आँकड़े में तार्किक रीड, सीपीयू समय और निष्पादन समय जैसी जानकारी होगी। ये मजबूत संकेत दे सकते हैं कि समस्या क्या है (जैसे। बड़ा स्कैन बनाम अवरोध)। डेटा की व्याख्या कैसे करें, इसके लिए समस्या प्रश्नों की पहचान करना देखें ।

इसके अलावा, यह पैरामीटर सूँघने की समस्या नहीं है। मैंने देखा है कि पहले, और यह नहीं है, क्योंकि जब भी मैं SSMS में varaibles को हार्ड-कोड करता हूं, तब भी मुझे धीमा प्रदर्शन मिलता है।

मैं आश्वस्त नहीं हूं। SSMS में हार्ड-कोडिंग चर साबित नहीं करते हैं कि पिछले खराब निष्पादन योजना को तिरछा इनपुट के खिलाफ संकलित नहीं किया गया था। कृपया विषय पर एक बहुत अच्छे लेख के लिए पैरामीटर सूँघना, एम्बेड करना और RECOMPILE विकल्प पढ़ें। अनुप्रयोग में धीमा, SSMS में तेज? प्रदर्शन रहस्यों को समझना एक और उत्कृष्ट संदर्भ है।

मैंने इन छोटे प्रयोगों से (शायद गलत तरीके से) निष्कर्ष निकाला है कि धीमे-धीमे का कारण यह है कि SQL की कैश्ड निष्पादन योजना कैसे सेट की जाती है - जब क्वेरी थोड़ी अलग होती है, तो उसे एक नई निष्पादन योजना बनानी होती है।

इसे आसानी से परखा जा सकता है। SET STATISTICS TIME ONआप संकलन बनाम निष्पादन समय दिखाएगा। SQL सर्वर: सांख्यिकी प्रदर्शन काउंटर यह भी बताएंगे कि क्या संकलन एक मुद्दा है (स्पष्ट रूप से, मुझे इसकी संभावना नहीं है)।

हालांकि, कुछ ऐसा ही है जो आपको हिट कर सकता है: क्वेरी अनुदान गेट। पढ़ें समझौता एसक्यूएल सर्वर स्मृति अनुदान जानकारी के लिए। यदि आपकी क्वेरी एक पल में एक बड़े अनुदान का अनुरोध करती है, तो कोई मेमोरी उपलब्ध नहीं है, तो उसे इंतजार करना होगा, और यह सब आवेदन के लिए 'धीमी गति से निष्पादन' के रूप में दिखेगा। प्रतीक्षा सूचना आँकड़े का विश्लेषण करने पर पता चलेगा कि क्या यह मामला है।

क्या मापना है और क्या देखना है, इसके बारे में अधिक सामान्य चर्चा के लिए, SQL सर्वर प्रदर्शन का विश्लेषण कैसे करें देखें


7

यह SQL सर्वर में जटिल प्रश्नों को चलाने का प्रतिबंध है। सौभाग्य से, ऐसा अक्सर नहीं होता है।

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

OPTION (MERGE JOIN, HASH JOIN)

यह आम तौर पर अतीत में मेरे लिए इस समस्या को तय करता है।

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


1
निष्पादन योजना वास्तव में नेस्टेड लूप जॉइन का उपयोग कर रही है। हालाँकि, जब मैं आपके सुझाव के अनुसार संकेत देता हूं, तो मुझे यह त्रुटि मिलती है: "क्वेरी प्रोसेसर इस क्वेरी में परिभाषित संकेतों के कारण क्वेरी योजना नहीं बना सका। किसी संकेत को निर्दिष्ट किए बिना और SET FORCEPLAN का उपयोग किए बिना क्वेरी को फिर से सबमिट करें।" जब मैं OPTION (LOOP JOIN) जोड़ता हूं, तो यह एक निष्पादन योजना बनाएगा, लेकिन मुझे अभी भी धीरे-धीरे चलने में समस्या है। क्या आप इस मुद्दे में भाग गए हैं? ऐसा लगता है कि यह लूप जॉइन करने के लिए जरूरी है।

@ ट्रेवर। । । नहीं, मैंने वास्तव में इस समस्या को नहीं देखा है। शायद आपकी क्वेरी कुछ गैर-समीकरण (समान संकेतों का उपयोग नहीं कर रही है) कर रही है और ऑप्टिमाइज़र को नेस्टेड लूप जॉइन का उपयोग करना है।
गॉर्डन लिनोफ

3

आमतौर पर यह एक लापता सूचकांक होता है जो इस तरह का मुद्दा बनता है।

मैं आमतौर पर SQL प्रबंधन स्टूडियो का उपयोग करके क्वेरी चला रहा हूं और 'वास्तविक निष्पादन योजना (CTRL + M)' को सक्षम कर रहा हूं और पता लगाता हूं कि कौन सा प्रतिशत सबसे बड़ा है।

आवेदन टोंटी पर ध्यान केंद्रित नहीं करता है, लेकिन आप इसे "जल्दी से" बस परिणाम में देख सकते हैं।

यहाँ उदाहरण: 48PercentForTop


2
हालांकि, एक सूचकांक अचानक "लापता" नहीं होगा, इसलिए जब यह प्रदर्शन में सुधार कर सकता है तो यह समस्या की व्याख्या नहीं करता है
Fowl

3

मैंने हाल ही में इसी मुद्दे का अनुभव किया जो मुझे इस पृष्ठ पर लाया।

@MartinSmith कुछ उस समय था जब उसने आपके आँकड़ों को अपडेट करने और योजना की व्याख्या करने की सिफारिश की थी। मैं यह जोड़ना चाहूंगा कि आपको यह सुनिश्चित करने की कोशिश करनी चाहिए कि आप चलने वाले कामों / प्रश्नों पर एक नज़र डालें जो ताले बना सकते हैं और इस तरह प्रतिक्रिया समय धीमा कर सकते हैं।

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

मैं उम्मीद करता हूं कि इससे किसी की मदद होगी


0

जब आपको T-SQL \ Procedure में प्रदर्शन समस्या दिखाई देती है, तो आपको यह भी जांचना होगा कि कोई सर्वर बैकअप या कोई Archiving \ Indexing जॉब चल रही है या नहीं।

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