हमारे ग्राहकों में से एक पर, हमारे आवेदन पर कुछ प्रदर्शन समस्याएँ हैं। यह एक .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) का उपयोग करता है, लेकिन सर्वर हमारे द्वारा नहीं बल्कि हमारे क्लाइंट द्वारा इंस्टॉल और कॉन्फ़िगर किए गए हैं।
क्या कोई मुझे इस डेटा की कुछ और समझ बनाने में मदद कर सकता है? क्या कोई मुझे समझने में हाथ दे सकता है कि क्या हो रहा है? क्या कुछ है जो मैं सर्वर पर कोशिश कर सकता हूं और चीजों को समझ सकता हूं? क्या मुझे एप्लिकेशन डेवलपमेंट टीम से बात करनी चाहिए?
exec()
समारोह का उपयोग मनाया व्यवहार की व्याख्या करेगा। इस मामले मेंsp_executesql
सामान्य रूप से डायनेमिक SQL कथनों के साथ समस्याओं का समाधान किया जाता है।