विशेष उदाहरण के लिए डेटाबेस द्वारा CPU उपयोग कैसे प्राप्त करें?


15

मैंने डेटाबेस द्वारा सीपीयू के उपयोग का पता लगाने के लिए निम्नलिखित प्रश्नों को पाया है, लेकिन वे अलग-अलग परिणाम दिखा रहे हैं:

WITH DB_CPU_Stats
AS
(
    SELECT DatabaseID, DB_Name(DatabaseID) AS [DatabaseName], 
      SUM(total_worker_time) AS [CPU_Time_Ms]
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY (
                    SELECT CONVERT(int, value) AS [DatabaseID] 
                  FROM sys.dm_exec_plan_attributes(qs.plan_handle)
                  WHERE attribute = N'dbid') AS F_DB
    GROUP BY DatabaseID
)
SELECT ROW_NUMBER() OVER(ORDER BY [CPU_Time_Ms] DESC) AS [row_num],
       DatabaseName,
        [CPU_Time_Ms], 
       CAST([CPU_Time_Ms] * 1.0 / SUM([CPU_Time_Ms]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CPUPercent]
FROM DB_CPU_Stats
--WHERE DatabaseID > 4 -- system databases
--AND DatabaseID <> 32767 -- ResourceDB
ORDER BY row_num OPTION (RECOMPILE);

उपरोक्त क्वेरी बताती है कि समस्या मेरे एक डेटाबेस (लगभग 96%) के साथ है।

और नीचे दी गई क्वेरी बताती है कि यह मुद्दा मास्टर और वितरण डेटाबेस (लगभग 90%) के साथ है:

DECLARE @total INT
SELECT @total=sum(cpu) FROM sys.sysprocesses sp (NOLOCK)
    join sys.sysdatabases sb (NOLOCK) ON sp.dbid = sb.dbid

SELECT sb.name 'database', @total 'system cpu', SUM(cpu) 'database cpu', CONVERT(DECIMAL(4,1), CONVERT(DECIMAL(17,2),SUM(cpu)) / CONVERT(DECIMAL(17,2),@total)*100) '%'
FROM sys.sysprocesses sp (NOLOCK)
JOIN sys.sysdatabases sb (NOLOCK) ON sp.dbid = sb.dbid
--WHERE sp.status = 'runnable'
GROUP BY sb.name
ORDER BY CONVERT(DECIMAL(4,1), CONVERT(DECIMAL(17,2),SUM(cpu)) / CONVERT(DECIMAL(17,2),@total)*100) desc

मैंने जाँच की sys.sysprocessesहै कि यह डिकम्प्रीटेड है। क्या इसका मतलब यह है कि दूसरी क्वेरी से परिणाम गलत हैं?

जवाबों:


14

हालांकि, मैं @ थोमस की तरह, "प्रति-डेटाबेस सीपीयू उपयोग" की चिंताओं के बारे में टिप्पणी पर पूरी तरह से @Aaron से सहमत हूं, या तो सटीक या उपयोगी है, मैं कम से कम इस सवाल का जवाब दे सकता हूं कि उन दो प्रश्नों में ऐसा क्यों है विभिन्न। और इसका कारण यह है कि वे अलग-अलग इंगित करेंगे कि कौन सा अधिक सटीक है, हालांकि उच्च स्तर की सटीकता अभी भी उस व्यक्ति के सापेक्ष है जो विशेष रूप से गलत है, इसलिए अभी भी वास्तव में सटीक नहीं है ;-)।

CPU जानकारी (यानी ) प्राप्त करने के लिए पहली क्वेरी sysinos_exec_query_stats का उपयोग करती है total_worker_time। यदि आप उस डीएमवी के लिए MSDN प्रलेखन से जुड़े हुए पृष्ठ पर जाते हैं, तो आपको एक छोटा, 3 वाक्य परिचय और उन वाक्यों में से 2 हमें इस जानकारी के संदर्भ ("यह कितना विश्वसनीय है) को समझने की आवश्यकता है।" और "यह कैसे तुलना करता है sys.sysprocesses")। वे दो वाक्य हैं:

SQL सर्वर में कैश्ड क्वेरी योजनाओं के लिए कुल प्रदर्शन आंकड़े देता है। ... जब कोई योजना कैश से निकाल दी जाती है, तो इसी पंक्तियों को इस दृश्य से हटा दिया जाता है

पहला वाक्य, " कुल प्रदर्शन के आंकड़े लौटाता है ", हमें बताता है कि इस DMV में जानकारी (कई अन्य लोगों की तरह) संचयी है और केवल उन प्रश्नों के लिए विशिष्ट नहीं है जो वर्तमान में चल रहे हैं। यह उस DMV में एक फ़ील्ड द्वारा इंगित किया गया है जो प्रश्न में क्वेरी का हिस्सा नहीं है execution_count, जो फिर से दिखाता है कि यह संचयी डेटा है। और इस डेटा को संचयी होना काफी आसान है क्योंकि आप कुछ मैट्रिक्स को विभाजित करके औसत, आदि प्राप्त कर सकते हैं execution_count

दूसरा वाक्य, "कैश से निकाले जा रहे प्लान भी इस डीएमवी से हटा दिए जाते हैं", यह इंगित करें कि यह पूरी तरह से एक पूरी तस्वीर नहीं है, खासकर यदि सर्वर में पहले से ही पूरी योजना कैश है और लोड के तहत है और इसलिए योजनाओं को समाप्त कर रहा है कुछ हद तक। इसके अलावा, अधिकांश डीएमवी को रीसेट किया जाता है जब सर्वर रीसेट करता है तो वे एक सच्चे इतिहास नहीं होते हैं भले ही ये पंक्तियों को योजना समाप्त होने पर हटाया नहीं गया था।

अब इसके साथ उपरोक्त विपरीत करते हैं sys.sysprocesses। यह सिस्टम दृश्य केवल वही दिखा रहा है जो वर्तमान में चल रहा है, बस sysinos_exec_connections , sysinos_exec_session , और sysinos_exec_requests (जो लिंक किए गए पृष्ठ पर कहा गया है sys.dm_exec_sessions) के संयोजन की तरह । यह sys.dm_exec_query_statsDMV की तुलना में सर्वर का एक बिल्कुल अलग दृष्टिकोण है जो प्रक्रिया पूरी होने के बाद भी डेटा को धारण करता है। मतलब, "दूसरी क्वेरी से परिणाम गलत हैं?" सवाल, वे गलत नहीं हैं, वे प्रदर्शन आँकड़ों के एक अलग पहलू (यानी समय-सीमा) से संबंधित हैं।

तो, क्वेरी का उपयोग sys.sysprocessesकेवल "अभी देख रहा है"। और का उपयोग कर क्वेरी sys.dm_exec_query_statsमें दिख रही है ज्यादातर (शायद) क्या एसक्यूएल सर्वर सेवा (या स्पष्ट रूप से सिस्टम रिबूट) के अंतिम पुनः आरंभ करने के बाद से नहीं हुआ है। सामान्य प्रदर्शन विश्लेषण के लिए ऐसा लगता है कि sys.dm_exec_query_statsयह कहीं बेहतर है, लेकिन फिर से, यह उपयोगी जानकारी को हर समय छोड़ देता है। और, दोनों ही मामलों में, आपको पहली बार में "database_id" मान की सटीकता के संबंध में प्रश्न टिप्पणियों (@ हटाए गए) में @Aaron द्वारा बनाए गए बिंदुओं पर भी विचार करने की आवश्यकता है (यानी यह केवल सक्रिय DB को दर्शाता है जिसने कोड शुरू किया था जरूरी नहीं कि जहां "मुद्दा" हो रहा हो)।

लेकिन, यदि आप केवल जरूरत है / क्या अभी सभी डेटाबेस भर में हो रहा है की भावना प्राप्त करना चाहते हैं, संभवतः क्योंकि चीजों को धीमा कर रहे हैं अभी, आप के संयोजन का उपयोग कर बेहतर होगा sys.dm_exec_connections, sys.dm_exec_sessionsऔर sys.dm_exec_requests(और नहीं पदावनत sys.sysprocesses)। बस ध्यान रखें कि आप प्रश्नों के लिए देख रहे हैं , डेटाबेस के लिए नहीं , क्योंकि प्रश्न कई डेटाबेस में शामिल हो सकते हैं, एक या अधिक डेटाबेस से यूडीएफ शामिल कर सकते हैं, आदि।


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

निम्न क्वेरी उच्च औसत CPU उपयोग के साथ प्रश्नों की पहचान करने में मदद करेगी। यह क्वेरी_स्टेट्स DMV में डेटा को सम्मिलित करता है क्योंकि ये रिकॉर्ड एक ही क्वेरी (हाँ, क्वेरी बैच का एक ही सबसेट) दिखा सकते हैं, प्रत्येक बार एक अलग निष्पादन योजना के साथ।

;WITH cte AS
(
  SELECT stat.[sql_handle],
         stat.statement_start_offset,
         stat.statement_end_offset,
         COUNT(*) AS [NumExecutionPlans],
         SUM(stat.execution_count) AS [TotalExecutions],
         ((SUM(stat.total_logical_reads) * 1.0) / SUM(stat.execution_count)) AS [AvgLogicalReads],
         ((SUM(stat.total_worker_time) * 1.0) / SUM(stat.execution_count)) AS [AvgCPU]
  FROM sys.dm_exec_query_stats stat
  GROUP BY stat.[sql_handle], stat.statement_start_offset, stat.statement_end_offset
)
SELECT CONVERT(DECIMAL(15, 5), cte.AvgCPU) AS [AvgCPU],
       CONVERT(DECIMAL(15, 5), cte.AvgLogicalReads) AS [AvgLogicalReads],
       cte.NumExecutionPlans,
       cte.TotalExecutions,
       DB_NAME(txt.[dbid]) AS [DatabaseName],
       OBJECT_NAME(txt.objectid, txt.[dbid]) AS [ObjectName],
       SUBSTRING(txt.[text], (cte.statement_start_offset / 2) + 1,
       (
         (CASE cte.statement_end_offset 
           WHEN -1 THEN DATALENGTH(txt.[text])
           ELSE cte.statement_end_offset
          END - cte.statement_start_offset) / 2
         ) + 1
       )
FROM cte
CROSS APPLY sys.dm_exec_sql_text(cte.[sql_handle]) txt
ORDER BY cte.AvgCPU DESC;

है AvgCPUमिलीसेकेंड में?
कोलोब कैनियन

हाय @KolobCanyon। Sysinos_exec_query_stats के दस्तावेज़ीकरण के अनुसार , total_worker_time" CPU समय की कुल राशि, microseconds (लेकिन केवल मिलीसेकंड के लिए सटीक) में रिपोर्ट की गई है, जो इस योजना के संकलित होने के बाद से खपत हो गई थी। " क्या उससे मदद हुई? इसे आसानी से मिलीसेकंड में परिवर्तित किया जा सकता है यदि आप इसे इस रूप में देखना चाहते हैं।
सोलोमन रटज़की

1

मैंने 0 त्रुटियों द्वारा विभाजन के लिए क्वेरी समायोजित की है और एक्सेल की कॉपी / पेस्ट के लिए अनुकूलित कॉलम नाम हैं।

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
GO
WITH DB_CPU_Stats
AS
(
    SELECT DatabaseID, isnull(DB_Name(DatabaseID),case DatabaseID when 32767 then 'Internal ResourceDB' else CONVERT(varchar(255),DatabaseID)end) AS [DatabaseName], 
      SUM(total_worker_time) AS [CPU_Time_Ms],
      SUM(total_logical_reads)  AS [Logical_Reads],
      SUM(total_logical_writes)  AS [Logical_Writes],
      SUM(total_logical_reads+total_logical_writes)  AS [Logical_IO],
      SUM(total_physical_reads)  AS [Physical_Reads],
      SUM(total_elapsed_time)  AS [Duration_MicroSec],
      SUM(total_clr_time)  AS [CLR_Time_MicroSec],
      SUM(total_rows)  AS [Rows_Returned],
      SUM(execution_count)  AS [Execution_Count],
      count(*) 'Plan_Count'
    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY (
                    SELECT CONVERT(int, value) AS [DatabaseID] 
                  FROM sys.dm_exec_plan_attributes(qs.plan_handle)
                  WHERE attribute = N'dbid') AS F_DB
    GROUP BY DatabaseID
)
SELECT ROW_NUMBER() OVER(ORDER BY [CPU_Time_Ms] DESC) AS [Rank_CPU],
       DatabaseName,
       [CPU_Time_Hr] = convert(decimal(15,2),([CPU_Time_Ms]/1000.0)/3600) ,
        CAST([CPU_Time_Ms] * 1.0 / SUM(case [CPU_Time_Ms] when 0 then 1 else [CPU_Time_Ms] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CPU_Percent],
       [Duration_Hr] = convert(decimal(15,2),([Duration_MicroSec]/1000000.0)/3600) , 
       CAST([Duration_MicroSec] * 1.0 / SUM(case [Duration_MicroSec] when 0 then 1 else [Duration_MicroSec] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Duration_Percent],    
       [Logical_Reads],
        CAST([Logical_Reads] * 1.0 / SUM(case [Logical_Reads] when 0 then 1 else [Logical_Reads] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Logical_Reads_Percent],      
       [Rows_Returned],
        CAST([Rows_Returned] * 1.0 / SUM(case [Rows_Returned] when 0 then 1 else [Rows_Returned] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Rows_Returned_Percent],
       [Reads_Per_Row_Returned] = [Logical_Reads]/(case [Rows_Returned] when 0 then 1 else [Rows_Returned] end),
       [Execution_Count],
        CAST([Execution_Count] * 1.0 / SUM(case [Execution_Count]  when 0 then 1 else [Execution_Count] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Execution_Count_Percent],
       [Physical_Reads],
       CAST([Physical_Reads] * 1.0 / SUM(case [Physical_Reads] when 0 then 1 else [Physical_Reads] end ) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Physcal_Reads_Percent], 
       [Logical_Writes],
        CAST([Logical_Writes] * 1.0 / SUM(case [Logical_Writes] when 0 then 1 else [Logical_Writes] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Logical_Writes_Percent],
       [Logical_IO],
        CAST([Logical_IO] * 1.0 / SUM(case [Logical_IO] when 0 then 1 else [Logical_IO] end) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Logical_IO_Percent],
       [CLR_Time_MicroSec],
       CAST([CLR_Time_MicroSec] * 1.0 / SUM(case [CLR_Time_MicroSec] when 0 then 1 else [CLR_Time_MicroSec] end ) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CLR_Time_Percent],
       [CPU_Time_Ms],[CPU_Time_Ms]/1000 [CPU_Time_Sec],
       [Duration_MicroSec],[Duration_MicroSec]/1000000 [Duration_Sec]
FROM DB_CPU_Stats
WHERE DatabaseID > 4 -- system databases
AND DatabaseID <> 32767 -- ResourceDB
ORDER BY [Rank_CPU] OPTION (RECOMPILE);

0

मुझे सीपीयू क्वेरी sys.dm_exec_query_statsइतनी पसंद आई कि मैंने इसे बढ़ा दिया। यह अभी भी सीपीयू द्वारा रैंक किया गया है, लेकिन मैंने एक बेहतर सर्वर प्रोफाइल प्राप्त करने के लिए अन्य योगों और पर्चों को जोड़ा। यह एक्सेल में अच्छी तरह से कॉपी करता है और प्रतिशत कॉलम पर सशर्त रंग प्रारूपण के साथ, सबसे खराब संख्या अच्छी तरह से बाहर निकलती है। मैंने 3 रंगों के साथ 'ग्रेडेड कलर स्केल' का इस्तेमाल किया; उच्च मूल्यों के लिए एक गुलाब का रंग, मध्य के लिए पीला, कम के लिए हरा।

मैंने एक लेबल जोड़ा database id 32676जिसके लिए आंतरिक SQL संसाधन डेटाबेस है। मैं समय के उपयोग की बेहतर समझ पाने के लिए सीपीयू और अवधि को घंटों में परिवर्तित करता हूं।

WITH DB_CPU_Stats
AS
(
    SELECT DatabaseID, isnull(DB_Name(DatabaseID),case DatabaseID when 32767 then 'Internal ResourceDB' else CONVERT(varchar(255),DatabaseID)end) AS [DatabaseName], 
      SUM(total_worker_time) AS [CPU Time Ms],
      SUM(total_logical_reads)  AS [Logical Reads],
      SUM(total_logical_writes)  AS [Logical Writes],
      SUM(total_logical_reads+total_logical_writes)  AS [Logical IO],
      SUM(total_physical_reads)  AS [Physical Reads],
      SUM(total_elapsed_time)  AS [Duration MicroSec],
      SUM(total_clr_time)  AS [CLR Time MicroSec],
      SUM(total_rows)  AS [Rows Returned],
      SUM(execution_count)  AS [Execution Count],
      count(*) 'Plan Count'

    FROM sys.dm_exec_query_stats AS qs
    CROSS APPLY (
                    SELECT CONVERT(int, value) AS [DatabaseID] 
                  FROM sys.dm_exec_plan_attributes(qs.plan_handle)
                  WHERE attribute = N'dbid') AS F_DB
    GROUP BY DatabaseID
)
SELECT ROW_NUMBER() OVER(ORDER BY [CPU Time Ms] DESC) AS [Rank CPU],
       DatabaseName,
       [CPU Time Hr] = convert(decimal(15,2),([CPU Time Ms]/1000.0)/3600) ,
        CAST([CPU Time Ms] * 1.0 / SUM([CPU Time Ms]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CPU Percent],
       [Duration Hr] = convert(decimal(15,2),([Duration MicroSec]/1000000.0)/3600) , 
       CAST([Duration MicroSec] * 1.0 / SUM([Duration MicroSec]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Duration Percent],    
       [Logical Reads],
        CAST([Logical Reads] * 1.0 / SUM([Logical Reads]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Logical Reads Percent],      
       [Rows Returned],
        CAST([Rows Returned] * 1.0 / SUM([Rows Returned]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Rows Returned Percent],
       [Reads Per Row Returned] = [Logical Reads]/[Rows Returned],
       [Execution Count],
        CAST([Execution Count] * 1.0 / SUM([Execution Count]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Execution Count Percent],
       [Physical Reads],
       CAST([Physical Reads] * 1.0 / SUM([Physical Reads]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Physcal Reads Percent], 
       [Logical Writes],
        CAST([Logical Writes] * 1.0 / SUM([Logical Writes]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Logical Writes Percent],
       [Logical IO],
        CAST([Logical IO] * 1.0 / SUM([Logical IO]) OVER() * 100.0 AS DECIMAL(5, 2)) AS [Logical IO Percent],
       [CLR Time MicroSec],
       CAST([CLR Time MicroSec] * 1.0 / SUM(case [CLR Time MicroSec] when 0 then 1 else [CLR Time MicroSec] end ) OVER() * 100.0 AS DECIMAL(5, 2)) AS [CLR Time Percent],
       [CPU Time Ms],[CPU Time Ms]/1000 [CPU Time Sec],
       [Duration MicroSec],[Duration MicroSec]/1000000 [Duration Sec]
FROM DB_CPU_Stats
--WHERE DatabaseID > 4 -- system databases
--AND DatabaseID <> 32767 -- ResourceDB
ORDER BY [Rank CPU] OPTION (RECOMPILE);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.