sql sql server数据库cpu用法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql sql server数据库cpu用法相关的知识,希望对你有一定的参考价值。
-----------------------------------------------------------------------------------------------------------
-- SQL Server - Check which database is spiking the CPU
-----------------------------------------------------------------------------------------------------------
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);
-----------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
--This first thing to check if CPU is at 100% is to look for parallel queries:
-- Tasks running in parallel (filtering out MARS requests below):
SELECT *
FROM sys.dm_os_tasks AS t
WHERE t.session_id IN (
SELECT t1.session_id
FROM sys.dm_os_tasks AS t1
GROUP BY t1.session_id
HAVING count(*) > 1
AND min(t1.request_id) = max(t1.request_id)
);
-- Requests running in parallel:
SELECT *
FROM sys.dm_exec_requests AS r
INNER JOIN (
SELECT t1.session_id
,min(t1.request_id)
FROM sys.dm_os_tasks AS t1
GROUP BY t1.session_id
HAVING count(*) > 1
AND min(t1.request_id) = max(t1.request_id)
) AS t(session_id, request_id) ON r.session_id = t.session_id
AND r.request_id = t.request_id;
--When you suspect SQL Server is waiting on CPU and CPU is constantly spiked on 90-100%, then it would wise to check the Top Waits Stats on SQL Server to see if the Top Waits is on “CXPACKET” by using Top Waits Rollup Query here.
--Most of the time, DBA needs to find the culprit queries which are using high CPU and try to optimize it them by designing proper indexes or by rewriting the SQL more efficiently.
--The queries useful in troubleshooting CPU Bottleneck issues, which are used by me are given below:
--To find queries which are using the most cumulative CPU
SELECT highest_cpu_queries.plan_handle
,highest_cpu_queries.total_worker_time
,q.dbid
,q.objectid
,q.number
,q.encrypted
,q.[text]
FROM (
SELECT TOP 50 qs.plan_handle
,qs.total_worker_time
FROM sys.dm_exec_query_stats qs
ORDER BY qs.total_worker_time DESC
) AS highest_cpu_queries
CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS q
ORDER BY highest_cpu_queries.total_worker_time DESC
--If high runnable tasks count is found by below query then we have is a symptom of a CPU bottleneck.
SELECT scheduler_id
,current_tasks_count
,runnable_tasks_count
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255
--Use below query to find Signal Waits (CPU waits) for instance(above 10-15% is usually a sign of CPU pressure)
SELECT CAST(100.0 * SUM(signal_wait_time_ms) / SUM(wait_time_ms) AS NUMERIC(20, 2)) AS [%signal (cpu) waits]
,CAST(100.0 * SUM(wait_time_ms - signal_wait_time_ms) / SUM(wait_time_ms) AS NUMERIC(20, 2)) AS [%resource waits]
FROM sys.dm_os_wait_stats WITH (NOLOCK)
OPTION (RECOMPILE);
--Use the below query to Get Average Task Counts (run multiple times, note highest values)
SELECT AVG(current_tasks_count) AS [Avg Task Count]
,AVG(runnable_tasks_count) AS [Avg Runnable Task Count]
,AVG(pending_disk_io_count) AS [AvgPendingDiskIOCount]
FROM sys.dm_os_schedulers WITH (NOLOCK)
WHERE scheduler_id < 255
OPTION (RECOMPILE);
--The below query can be used to find Top 50 SQL Statements taking a high cpu.
SELECT TOP 50 sum(qs.total_worker_time) AS total_cpu_time
,sum(qs.execution_count) AS total_execution_count
,count(*) AS number_of_statements
,qs.plan_handle
FROM sys.dm_exec_query_stats qs
GROUP BY qs.plan_handle
ORDER BY sum(qs.total_worker_time) DESC
--The below query useful in finding time spent optimising query
SELECT *
FROM sys.dm_exec_query_optimizer_info
--To check plan_generation_num -- amount of time query was recompiled
SELECT TOP 25 sql_text.TEXT
,sql_handle
,plan_generation_num
,execution_count
,dbid
,objectid
FROM sys.dm_exec_query_stats a
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sql_text
WHERE plan_generation_num > 1
ORDER BY plan_generation_num DESC
--To check all active requests that are running in parallel for a given session
SELECT r.session_id
,r.request_id
,max(isnull(exec_context_id, 0)) AS number_of_workers
,r.sql_handle
,r.statement_start_offset
,r.statement_end_offset
,r.plan_handle
FROM sys.dm_exec_requests r
INNER JOIN sys.dm_os_tasks t ON r.session_id = t.session_id
INNER JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
WHERE s.is_user_process = 0x1
GROUP BY r.session_id
,r.request_id
,r.sql_handle
,r.plan_handle
,r.statement_start_offset
,r.statement_end_offset
HAVING max(isnull(exec_context_id, 0)) > 0
--To check how much memory SQL Server has allocated through AWE mechanism
SELECT sum(awe_allocated_kb) / 1024 AS [AWE allocated, Mb]
FROM sys.dm_os_memory_clerks
以上是关于sql sql server数据库cpu用法的主要内容,如果未能解决你的问题,请参考以下文章