环境详细信息:SQL Server 2008 R2。我有在 JBoss 上运行的应用程序,它们使用 JDBC 驱动程序访问数据库。
问题:我的在线数据库服务器 CPU 使用率很高。
使用以下查询,我能够确定有 2 个查询(Select 命令)处于挂起状态(等待类型 - CXPACKET)近 10 分钟并继续进行。我相信这是导致 CPU 使用率高的原因。
USE MASTER GO
SELECT scheduler_id ,
runnable_tasks_count ,
pending_disk_io_count
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255
SELECT qs.percent_complete ,
qs.session_id ,
scheduler_id ,
blocking_session_id ,
qs.status ,
command ,
wait_time ,
wait_type ,
last_wait_type ,
wait_resource ,
ST.text ,
host_name ,
program_name /*
,SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
( (CASE statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE QS.statement_end_offset END - QS.statement_start_offset )/2 ) + 1) AS statement_text */ --, qp.*
FROM sys.dm_exec_requests qs
LEFT JOIN sys.dm_exec_sessions es ON ( qs.session_id = es.session_id )
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS ST
-- CROSS APPLY sys.dm_exec_query_plan(QS.sql_handle) as qp where qs.session_id = 50 and qs.session_id != @@SPID
SELECT CASE WHEN Requests.sql_handle IS NULL THEN ' '
ELSE SUBSTRING(Statements.text,
( Requests.statement_start_offset + 2 ) / 2,
( CASE WHEN Requests.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), Statements.text))
* 2
ELSE Requests.statement_end_offset
END - Requests.statement_start_offset ) / 2)
END AS StatementText ,
QueryPlans.query_plan AS QueryPlan ,
Statements.text AS Batch_Text ,
Sessions.session_id ,
Sessions.Login_Name ,
Sessions.Host_Name ,
Sessions.Program_Name ,
Sessions.Client_Interface_Name ,
Requests.wait_time ,
Requests.cpu_time ,
Requests.total_elapsed_time ,
Requests.reads ,
Requests.writes ,
Requests.logical_reads ,
Requests.row_count ,
Requests.granted_query_memory * 8 / 1024 AS Granted_Query_Memory_MB ,
LEN(Statements.text) AS Batch_Text_Length ,
Requests.statement_start_offset / 2 AS Statement_Start_Offset ,
CASE WHEN Requests.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), Statements.text)) * 2
ELSE Requests.statement_end_offset
END / 2 AS Statement_End_Position ,
( CASE WHEN Requests.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), Statements.text)) * 2
ELSE Requests.statement_end_offset
END - Requests.statement_start_offset ) / 2 AS Statement_Text_Length
FROM sys.dm_exec_session Sessions
INNER JOIN sys.dm_exec_requests Requests ON Sessions.session_id = Requests.session_id
CROSS APPLY sys.dm_exec_sql_text(sql_handle) Statements
CROSS APPLY sys.dm_exec_query_plan(plan_handle) QueryPlans
WHERE Sessions.session_id != @@SPID
SELECT *
FROM sys.dm_exec_requests
WHERE blocking_session_id != 0
Run Code Online (Sandbox Code Playgroud)
关于如何在暂停状态下终止这些查询的任何建议?
虽然您已经接受了一个告诉您如何终止会话的答案,但这是一种可能会重复的问题,因此您可能应该意识到CXPACKET
等待类型本身不是问题,但往往表明存在问题执行并行查询。
Brent Ozar 发布了关于CXPACKET 等待是什么以及如何减少它们的很好的解释(带有视频)。例如,如果您的并行查询在 5 个 CPU 上运行,并且其中 4 个已完成分配的工作负载,则等待第 5 个 CPU 完成被标识为CXPACKET
等待。
您可以CXPACKET
通过研究在单个查询上设置最大并行度 (MAXDOP)和/或实例上并行度的成本阈值来开始缓解等待,文章中对这两者进行了解释。
归档时间: |
|
查看次数: |
22840 次 |
最近记录: |