在今天的大部分时间里,我的SQL Server CPU大约占90%。
由于它一直在使用,我无法重新启动它。
是否有可能找出SQL中导致这种CPU过载的原因?
我已经运行了SQL事件探查器,但是发生了很多事情,很难确定是否有任何特别的原因引起了它。
我已经运行了sp_who2,但是不确定所有含义到底是什么,以及是否有可能在此处确定可能的问题。
为了阻止任何“可能只是被大量使用”的响应,今天才从完全正常的活动水平开始。
我一直在寻找在SQL中导致CPU崩溃的原因。
Answers:
我在这里进行尽职调查,您已确认SQL进程实际上消耗了CPU(perfmon进程类别计数器将确认这一点)。通常,在这种情况下,需要对相关性能计数器进行采样,并将其与在正常负载运行条件下建立的基准进行比较。解决此问题后,建议您为以后的比较建立这样的基准。
您可以确切找到每个CPU周期在SQL上花费的位置。但是知道在哪里看需要很多知识和经验。是SQL 2005/2008还是2000?幸运的是,对于2005年及以后的版本,有几个现成的解决方案。约翰·萨姆森(John Samson)的答案已经为您提供了很好的指导。我想添加一条建议,以下载和安装SQL Server性能仪表板报告。其中一些报告包括按时间或按I / O的热门查询,最常用的数据文件等,您可以快速了解问题所在。输出既是数字的又是图形的,因此对于初学者来说更有用。
我还建议使用Adam的Who is Active脚本,尽管这要先进一些。
最后但并非最不重要的一点是,我建议您下载并阅读有关性能分析的MS SQL客户咨询团队白皮书:SQL 2005 Waits and Queues。
我的建议还应该看一下I / O。如果您向服务器添加了一个浪费缓冲池的负载(即,它需要大量数据以至于它从内存中逐出了缓存的数据页),那么结果将是CPU的显着增加(听起来令人惊讶,但这是事实)。罪魁祸首通常是一个新的查询,它端对端扫描一个大表。
此查询使用DMV来识别CPU成本最高的查询
SELECT TOP 20
qs.sql_handle,
qs.execution_count,
qs.total_worker_time AS Total_CPU,
total_CPU_inSeconds = --Converted from microseconds
qs.total_worker_time/1000000,
average_CPU_inSeconds = --Converted from microseconds
(qs.total_worker_time/1000000) / qs.execution_count,
qs.total_elapsed_time,
total_elapsed_time_inSeconds = --Converted from microseconds
qs.total_elapsed_time/1000000,
st.text,
qp.query_plan
FROM
sys.dm_exec_query_stats AS qs
CROSS APPLY
sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS APPLY
sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY
qs.total_worker_time DESC
有关完整的说明,请参见:如何通过CPU确定最昂贵的SQL Server查询
您可以运行SQL事件探查器,并按CPU或持续时间进行过滤,以便排除所有“小东西”。然后,确定某个问题(例如特定存储的proc)的运行时间比实际运行的时间要长得多(应该是缺少索引等)应该容易得多。
两个警告:
但是通常我从活动监视器或sp_who2开始。
将其中任何一个间隔几秒钟。您将检测到CPU连接过高。或者:将存储的CPU存储在局部变量WAITFOR DELAY中,比较存储的和当前的CPU值
select * from master..sysprocesses
where status = 'runnable' --comment this out
order by CPU
desc
select * from master..sysprocesses
order by CPU
desc
可能不是最优雅的,但它会有效且快速。
您可以在此处找到一些有用的查询:
对我来说,这很有帮助:
SELECT s.session_id,
r.status,
r.blocking_session_id 'Blk by',
r.wait_type,
wait_resource,
r.wait_time / (1000 * 60) 'Wait M',
r.cpu_time,
r.logical_reads,
r.reads,
r.writes,
r.total_elapsed_time / (1000 * 60) 'Elaps M',
Substring(st.TEXT,(r.statement_start_offset / 2) + 1,
((CASE r.statement_end_offset
WHEN -1
THEN Datalength(st.TEXT)
ELSE r.statement_end_offset
END - r.statement_start_offset) / 2) + 1) AS statement_text,
Coalesce(Quotename(Db_name(st.dbid)) + N'.' + Quotename(Object_schema_name(st.objectid, st.dbid)) + N'.' +
Quotename(Object_name(st.objectid, st.dbid)), '') AS command_text,
r.command,
s.login_name,
s.host_name,
s.program_name,
s.last_request_end_time,
s.login_time,
r.open_transaction_count
FROM sys.dm_exec_sessions AS s
JOIN sys.dm_exec_requests AS r
ON r.session_id = s.session_id
CROSS APPLY sys.Dm_exec_sql_text(r.sql_handle) AS st
WHERE r.session_id != @@SPID
ORDER BY r.cpu_time desc
在状态字段,wait_type和cpu_time中,您可以找到当前正在运行的消耗CPU最多的任务。
SQL Server Performance Dashboard Reports
。