Performance analysis of SQL Server — about CPU

–查询编译以来 cpu耗时总量最多的前50条(Total_woker_time)

SELECT TOP 50

total_worker_time/1000 AS [总消耗CPU 时间(ms)],

execution_count [运行次数],

qs.total_worker_time/qs.execution_count/1000 AS [平均消耗CPU 时间(ms)],

last_execution_time AS [最后一次执行时间],

max_worker_time /1000 AS [最大执行时间(ms)],

SUBSTRING(qt.text,qs.statement_start_offset/2+1,

(CASE WHEN qs.statement_end_offset = -1

THEN DATALENGTH(qt.text)

ELSE qs.statement_end_offset END -qs.statement_start_offset)/2 + 1)

AS [使用CPU的语法], qt.text [完整语法],

qt.dbid, dbname=db_name(qt.dbid),

qt.objectid,object_name(qt.objectid,qt.dbid) ObjectName

FROM sys.dm_exec_query_stats qs WITH(nolock)

CROSS apply sys.dm_exec_sql_text(qs.sql_handle) AS qt

WHERE execution_count>1

ORDER BY total_worker_time DESC

sql server系统作为一个整体性,它都是紧密相连的,例如:解决了sql语句中I/O开销较多的问题,那对应的CPU开销也会减少,反之解决了CPU开销最多的,那对应I/O开销也会减少。解决I/O开销后CPU耗时也减少,是因为CPU下的Worker线程需要扫描I/O页数就少了,出现的资源锁的阻塞也减少了

2.数据库CPU很高,查询问题的SQL,根据时间“等待毫秒”,查出问题的SQL SELECT spid, blocked, DB_NAME(sp.dbid)
AS DBName, program_name, waitresource, sp.waittime 等待毫秒, sp.stmt_start,
lastwaittype, sp.loginame, sp.Status, sp.hostname, a.[Text] AS [TextData],
SUBSTRING(A.text, sp.stmt_start / 2, (CASE WHEN sp.stmt_end = -1 THEN
DATALENGTH(A.text) ELSE sp.stmt_end END – sp.stmt_start) / 2) AS [current_cmd]
FROM sys.sysprocesses AS sp OUTER APPLY sys.dm_exec_sql_text (sp.sql_handle) AS
A WHERE spid > 50 –and lastwaittype=‘HADR_SYNC_COMMIT‘ AND Status<>‘sleeping‘
ORDER BY sp.waittime desc;

3.案例分享
SQL Server导致CPU爆高,一般是异常SQL引起,怀疑是服务器的磁盘性能问题,停SQL服务,用测试一下磁盘的性能,磁盘性能的确不怎样,但是也没差到这样的地步。后来发现一条查询SQL,有3亿条,查询taskid字段没有索引,导致查询IO很慢,进而影响CPU爆高。后重建一张新的tb_log表,并在taskid字段加上索引,性能问题解决。