SQL सर्वर कथन SQL Server 2008 R2 पर रुक-रुक कर धीमा


13

हमारे ग्राहकों में से एक पर, हमारे आवेदन पर कुछ प्रदर्शन समस्याएँ हैं। यह एक .NET 3.5 वेब ऐप है जो SQL Server डेटाबेस पर डेटा का उपभोग और अद्यतन कर रहा है। वर्तमान में हमारे उत्पादन वातावरण में सामने के अंत के रूप में एक विंडोज 2008 आर 2 मशीन और पीछे के छोर पर एक एसक्यूएल सर्वर 2008 आर 2 क्लस्टर है। हमारा ऐप डेटाबेस से कनेक्ट करने के लिए COM + और MSDTC का उपयोग करता है।

यहाँ क्या हो रहा है: हमारे अंतिम उपयोगकर्ता कभी-कभी एप्लिकेशन में सुस्ती की शिकायत करते हैं। कुछ पृष्ठों को लोड होने में कुछ और समय लगने की उम्मीद है। यह पता लगाने की कोशिश करते हुए कि क्या हो रहा है, मैंने डेटाबेस पक्ष पर कुछ अजीब व्यवहार का पता लगाने में कामयाबी पाई जो प्रदर्शन में गिरावट का कारण हो सकता है। मैंने देखा कि कभी-कभी कुछ SQL स्टेटमेंट्स होते हैं जिन्हें चलाने में बहुत अधिक समय लगता है जो कि अपेक्षित होगा। मैं इन बयानों में से कुछ की पहचान करने में कामयाब रहा (मुख्य रूप से यह हमारे एप्लिकेशन की कुछ संग्रहीत प्रक्रियाओं का चालान है) लंबे समय तक चलने वाले प्रश्नों की पहचान करने के लिए प्रोफाइलर ट्रेस (TSQL_Duration टेम्पलेट के साथ) का उपयोग कर रहा है।

समस्या यह है कि जब मैं इन संग्रहीत प्रक्रियाओं को सीधे SQL प्रबंधन स्टूडियो पर डेटाबेस पर चलाता हूं तो वे कभी-कभी लंबे (लगभग 7/8 सेकंड) करते हैं, अन्य बार वे तेज होते हैं (1 सेकंड के तहत।)। मुझे नहीं पता कि ऐसा क्यों होता है और यह मुझे पागल कर रहा है, क्योंकि एसक्यूएल मशीन (4 कोर, 32 जीबी) किसी भी अन्य अनुप्रयोगों द्वारा उपयोग नहीं किया जा रहा है, और इन प्रश्नों को चलाने में लंबा समय नहीं लेना चाहिए।

डीबीए या एसक्यूएल सर्वर गुरु नहीं होने के कारण, मैं कुछ ऐसे सामानों को देखने की कोशिश कर रहा हूं जो समस्या को समझने में मेरी मदद कर सकते हैं। यहाँ मैंने जो प्रयास करने और समस्या को हल करने के लिए कदम उठाए हैं और जो मुझे अब तक पता चला है:

  • आवेदन द्वारा बुलाया TSQL कोड के सभी संग्रहीत प्रक्रियाओं में लिखा है।
  • मैंने SQL सर्वर प्रोफाइलर पर कुछ लंबे चलने वाले प्रश्नों की पहचान की, हालाँकि जब मैं इन्हें मैनेजमेंट स्टूडियो पर चलाता हूं तो उन्हें या तो चलाने में लंबा समय लगता है (4 से 10 सेकंड तक)। या जल्दी से (1 सेकंड के तहत) चलाएं। मैं मापदंडों में पारित समान डेटा के साथ सटीक समान क्वेरी चला रहा हूं। ये प्रश्न मुख्य रूप से उन में चयनित बयानों के साथ संग्रहीत प्रक्रियाएं हैं।
  • मैंने प्रतीक्षा करने की कोशिश की और कतारों के आंकड़ों को देखने की कोशिश की और यह पता लगाने की कोशिश की कि क्या कुछ संसाधनों पर प्रतीक्षा करने की प्रक्रियाएं हैं। मैंने निम्नलिखित प्रश्न चलाया:

WITH Waits AS
    (SELECT
        wait_type,
        wait_time_ms / 1000.0 AS WaitS,
        (wait_time_ms - signal_wait_time_ms) / 1000.0 AS ResourceS,
        signal_wait_time_ms / 1000.0 AS SignalS,
        waiting_tasks_count AS WaitCount,
        100.0 * wait_time_ms / SUM (wait_time_ms) OVER() AS Percentage,
        ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS RowNum
    FROM sys.dm_os_wait_stats
    WHERE wait_type NOT IN (
        'CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'RESOURCE_QUEUE', 'SLEEP_TASK',
        'SLEEP_SYSTEMTASK', 'SQLTRACE_BUFFER_FLUSH', 'WAITFOR', 'LOGMGR_QUEUE',
        'CHECKPOINT_QUEUE', 'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT',  'BROKER_TO_FLUSH',
        'BROKER_TASK_STOP', 'CLR_MANUAL_EVENT', 'CLR_AUTO_EVENT',     'DISPATCHER_QUEUE_SEMAPHORE',
        'FT_IFTS_SCHEDULER_IDLE_WAIT', 'XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN', 'BROKER_EVENTHANDLER',
        'TRACEWRITE', 'FT_IFTSHC_MUTEX', 'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
        'BROKER_RECEIVE_WAITFOR', 'ONDEMAND_TASK_QUEUE', 'DBMIRROR_EVENTS_QUEUE',
        'DBMIRRORING_CMD', 'BROKER_TRANSMITTER', 'SQLTRACE_WAIT_ENTRIES',
        'SLEEP_BPOOL_FLUSH', 'SQLTRACE_LOCK')
    )
SELECT
    W1.wait_type AS WaitType, 
    CAST (W1.WaitS AS DECIMAL(14, 2)) AS Wait_S,
    CAST (W1.ResourceS AS DECIMAL(14, 2)) AS Resource_S,
    CAST (W1.SignalS AS DECIMAL(14, 2)) AS Signal_S,
    W1.WaitCount AS WaitCount,
    CAST (W1.Percentage AS DECIMAL(4, 2)) AS Percentage,
    CAST ((W1.WaitS / W1.WaitCount) AS DECIMAL (14, 4)) AS AvgWait_S,
    CAST ((W1.ResourceS / W1.WaitCount) AS DECIMAL (14, 4)) AS AvgRes_S,
    CAST ((W1.SignalS / W1.WaitCount) AS DECIMAL (14, 4)) AS AvgSig_S
FROM Waits AS W1
    INNER JOIN Waits AS W2 ON W2.RowNum <= W1.RowNum
GROUP BY W1.RowNum, W1.wait_type, W1.WaitS, W1.ResourceS, W1.SignalS, W1.WaitCount,    W1.Percentage
HAVING SUM (W2.Percentage) - W1.Percentage < 95; -- percentage threshold
GO

यहाँ मुझे पता चला है:

  • जब मैं DBCC SQLPERF (लगभग 1 या 2 घंटे बाद) का उपयोग करके आँकड़े रीसेट करता हूं, तो मेरे पास सबसे अधिक प्रतीक्षा प्रकार SOS_SCHEDULER_YIELD और WRITELOG है।
  • समय के साथ (लगभग 1 दिन के निष्पादन के बाद), डेटाबेस पर सबसे अधिक होने वाले प्रतीक्षा प्रकार CXPACKET (67%) और OLEDB (17%) हैं, भले ही प्रत्येक के लिए औसत प्रतीक्षा समय लंबा नहीं है। मैंने यह भी देखा कि एसक्यूएल प्रोइलर पर पहचाने जाने वाले लंबे समय तक चलने वाले स्टेटमेंट एक संग्रहीत कार्यविधि पर कॉल होते हैं जो एक से अधिक परिणाम (अक्सर 3) पर लौटते हैं। क्या यहां परवादवाद की समस्या हो सकती है? क्या कोई तरीका है जिससे मैं पहचानने की कोशिश कर सकता हूं कि क्या यह समस्या का कारण है?
  • मैंने कहीं पढ़ा है कि OLEDB वेट लिंक्ड सर्वर जैसे OLEDB संसाधनों के कॉल के कारण हो सकता है। इंडेक्सिंग सर्विसेज मशीन (MSIDXS) से जुड़ने के लिए हमारे पास एक जुड़ा हुआ सर्वर है, हालांकि लंबे समय तक चलने वाले बयानों में से कोई भी उस लिंक किए गए सर्वर का उपयोग नहीं करता है।
  • LCK_M_X प्रकार के वेट के लिए मेरे पास उच्च औसत प्रतीक्षा समय (लगभग 1.5 सेकंड औसत) है, लेकिन ये प्रतीक्षा प्रकार अन्य प्रकारों की तुलना में बहुत अधिक बार नहीं होते हैं (उदाहरण के लिए, 64 LCK_M_X प्रतीक्षा करता है बनाम 10,823 CXKACKET समय की इसी अवधि में प्रतीक्षा करता है )।
  • एक बात मैंने गौर की कि MSDTC सेवा का क्लस्टर नहीं है। SQL सर्वर सेवा क्लस्टर की गई है, लेकिन MSDTC की नहीं। क्या इसकी वजह से प्रदर्शन प्रभावित हो सकता है? हम MSDTC का उपयोग कर रहे हैं क्योंकि हमारा ऐप डेटाबेस तक पहुंचने के लिए एंटरप्राइज सर्विसेज (DCOM) का उपयोग करता है, लेकिन सर्वर हमारे द्वारा नहीं बल्कि हमारे क्लाइंट द्वारा इंस्टॉल और कॉन्फ़िगर किए गए हैं।

क्या कोई मुझे इस डेटा की कुछ और समझ बनाने में मदद कर सकता है? क्या कोई मुझे समझने में हाथ दे सकता है कि क्या हो रहा है? क्या कुछ है जो मैं सर्वर पर कोशिश कर सकता हूं और चीजों को समझ सकता हूं? क्या मुझे एप्लिकेशन डेवलपमेंट टीम से बात करनी चाहिए?

जवाबों:


4

आपकी समस्या की विस्तृत व्याख्या के लिए धन्यवाद (वास्तव में सबसे अच्छे प्रश्नों में से एक)।

WRITELOG प्रतीक्षा का एक बहुत ही सामान्य प्रकार है, इसलिए इसके बारे में चिंता न करें। SOS_SCHEDULER_YIELD को देखते हुए CPU दबाव और CXPACKET को इंगित करता है, यह संभव है कि कुछ अनुपलब्ध अनुक्रमणिकाएँ हों और आप OLTP सिस्टम के लिए क्वेरीज़ से बहुत से डेटा पुनर्प्राप्त कर रहे हों। मेरा सुझाव है कि आप मिसिंग इंडेक्स डीएमवी को देखें और देखें कि क्या कोई इंडेक्स है (लगभग निश्चित रूप से कुछ से अधिक होगा) जो कि संदिग्ध प्रेक में हैं।

http://sqlfool.com/2009/04/a-look-at-missing-indexes/

http://troubleshootingsql.com/2009/12/30/how-to-find-out-the-missing-indexes-on-a-sql-server-2008-or-2005-instance-along-with-the- बनाने सूचकांक-आदेशों /

इस पर भी sqlblog.com पर जोनाथन केहियास की पोस्ट देखें।

इसके अलावा, पैरामीटर सूँघने पर एक नज़र डालें।

http://sommarskog.se/query-plan-mysteries.html

http://pratchev.blogspot.com/2007/08/parameter-sniffing.html

यह आपकी आवश्यकताओं के लिए प्रतिस्पर्धा का जवाब नहीं है, लेकिन एक अच्छा प्रारंभिक बिंदु है। यदि आपको अधिक विवरण की आवश्यकता है, तो हमें बताएं।


1

कर्मचारियों के कुछ संग्रहीत प्रक्रियाओं को फिर से लिखने के बाद हमारे पास एक समान मुद्दा था। यह पता चला कि अत्यधिक ब्रांचिंग और डायनेमिक एसक्यूएल बनाया जा रहा था, जहां क्लॉज काफी बदल गया था।

उदाहरण के लिए (पाठ्यक्रम का सरलीकृत):

यदि मॉडल "X" था जहां क्लॉज़ ProductCode के लिए कुछ निश्चित समान मूल्यों की तलाश करता था।
यदि मॉडल "Y" था, जहां क्लॉज ProductType के लिए कुछ निश्चित मूल्यों के बराबर देखा गया था ।

SQL सर्वर पहली बार संग्रहीत कार्यविधि निष्पादित होने पर इनपुट मापदंडों के आधार पर एक क्वेरी योजना बनाएगा। इसलिए, यदि क्वेरी प्लान "ProductCode" के बराबर लॉजिक पर बनाया गया है और आप "ProductType" के लिए पूछ रहे हैं, तो यह एक बेमेल क्वेरी प्लान के बराबर है और पूर्ण तालिका स्कैन में सबसे अधिक संभावित परिणाम है।

आप संग्रहीत प्रक्रिया के शीर्ष पर " RECOMPILE के साथ " रखने का प्रयास कर सकते हैं । निर्माण प्रक्रिया (लेनदेन-एसक्यूएल)

इसका वर्णन करने का सबसे अच्छा तरीका इस प्रकार है:

मान लीजिए कि आपके पास नामों और फ़ोन नंबरों की एक सूची है जो अंतिम नाम से क्रमबद्ध है। यह उनके अंतिम नाम (अंतिम नाम पर आधारित क्वेरी योजना) का उपयोग कर लोगों को खोजने के लिए बहुत अच्छा काम करता है। मान लीजिए कि आपको एरिया कोड 203 में सभी नामों और फोन नंबरों की आवश्यकता है। यदि आपकी सूची को अंतिम नाम द्वारा क्रमबद्ध किया गया है, तो सभी एरिया कोड 203 लोगों की पूरी सूची प्राप्त करने का एकमात्र तरीका शीर्ष से शुरू करना और प्रत्येक के माध्यम से क्रमिक रूप से पढ़ना है। हर रिकॉर्ड। (पूर्ण तालिका स्कैन)।


exec()समारोह का उपयोग मनाया व्यवहार की व्याख्या करेगा। इस मामले में sp_executesqlसामान्य रूप से डायनेमिक SQL कथनों के साथ समस्याओं का समाधान किया जाता है।
अंजह

1

यदि प्रश्न SSMS और ऐप में रुक-रुक कर तेजी से और धीमी गति से चल रहे हैं, तो आपके पास आंकड़े या पैरामीटर सूँघने का मुद्दा हो सकता है।

मैं इन संग्रहीत प्रक्रियाओं को निष्पादित करूंगा, फिर रूट ऑपरेटर (हरेक विवरण के बाईं ओर ग्रीन नोड) की संपत्तियों को खींचने के लिए निष्पादन योजना की समीक्षा करेंगे।

निष्पादन योजना में पंक्तियों की अनुमानित संख्या क्या है, बनाम कितने वास्तविक पंक्तियों को वापस किया गया?

क्या संकलित पैरामीटर वास्तविक क्वेरी पैरामीटर से मेल खाता है?

यदि निष्पादन योजना एक पैरामीटर के लिए बनाई गई थी जो केवल मुट्ठी भर पंक्तियों को लौटाती है, और आप एक ही प्रक्रिया को एक पैरामीटर के साथ चलाते हैं जो बड़ी संख्या में पंक्तियों को वापस करता है, तो SQL क्वेरी के लिए गलत निष्पादन योजना का उपयोग कर सकता है।

निष्पादन योजना के विकल्प एसक्यूएल आँकड़ों से निकटता से जुड़े हुए हैं, इसलिए नियमित आधार पर अपने आँकड़ों का पुनर्निर्माण करना एक अच्छा विचार है।

यदि आपके पास एक संग्रहीत कार्यविधि है जो कभी-कभी प्रदान किए गए पैरामीटर के आधार पर थोड़ी मात्रा में डेटा या विशाल मात्रा में डेटा लौटाती है, तो आपके पास पैरामीटर सूँघने की समस्या हो सकती है।

यदि आपके आँकड़ों को फिर से बनाने से समस्या का समाधान नहीं होता है, तो आप संग्रहीत प्रक्रिया में सबसे महंगे कथन (s) चला सकते हैं OPTION (RECOMPILE)


0

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

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