如何找出spid状态暂停的原因?spid在等待什么资源?

Mar*_*lli 35 sql sql-server optimization query-optimization sql-tuning

我跑了EXEC sp_who2 78,我得到以下结果:

sp_who2的结果为spid 78

我怎样才能找到其状态暂停的原因?

INSERT基于昂贵的查询,此过程非常繁重.一个大SELECT从几个表中获取数据,并写一些3-4百万行不同的表.

没有锁/块.

waittype它与是CXPACKET.我能理解,因为你可以在下面的图片中看到9个78.

关注我和我真正想知道的是为什么SPID78 号中的第1号被暂停.

我知道当a的状态SPID被暂停时,它意味着进程正在等待资源,并且当它获取其资源时它将恢复.

我怎样才能找到更多这方面的细节?什么资源?为什么不可用?

我使用了下面的代码以及其中的变化,但是我还能做些什么来找出SPID暂停的原因?

select * 
from sys.dm_exec_requests r
join sys.dm_os_tasks t on r.session_id = t.session_id
where r.session_id = 78
Run Code Online (Sandbox Code Playgroud)

我已经习惯了EXEC sp_who2 78.我得到的这个特殊spid78的结果如下:(分为3个图片以适应屏幕)

在此输入图像描述

Mar*_*lli 36

SUSPENDED:表示请求当前未处于活动状态,因为它正在等待资源.资源可以是用于读取页面的I/O,WAITit可以是网络上的通信,或者它正在等待锁定或锁存.一旦等待的任务完成,它将变为活动状态.例如,如果查询已发布I/O请求以读取完整表tblStudents的数据,则此任务将暂停,直到I/O完成.一旦I/O完成(表tblStudents的数据在内存中可用),查询将进入RUNNABLE队列.

因此,如果它正在等待,请检查wait_type列以了解它正在等待什么,并根据wait_time进行故障排除.

我已经开发了以下过程来帮助我,它包括WAIT_TYPE.

use master
go

CREATE PROCEDURE [dbo].[sp_radhe] 

AS
BEGIN

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT es.session_id AS session_id
,COALESCE(es.original_login_name, '') AS login_name
,COALESCE(es.host_name,'') AS hostname
,COALESCE(es.last_request_end_time,es.last_request_start_time) AS last_batch
,es.status
,COALESCE(er.blocking_session_id,0) AS blocked_by
,COALESCE(er.wait_type,'MISCELLANEOUS') AS waittype
,COALESCE(er.wait_time,0) AS waittime
,COALESCE(er.last_wait_type,'MISCELLANEOUS') AS lastwaittype
,COALESCE(er.wait_resource,'') AS waitresource
,coalesce(db_name(er.database_id),'No Info') as dbid
,COALESCE(er.command,'AWAITING COMMAND') AS cmd
,sql_text=st.text
,transaction_isolation =
    CASE es.transaction_isolation_level
    WHEN 0 THEN 'Unspecified'
    WHEN 1 THEN 'Read Uncommitted'
    WHEN 2 THEN 'Read Committed'
    WHEN 3 THEN 'Repeatable'
    WHEN 4 THEN 'Serializable'
    WHEN 5 THEN 'Snapshot'
END
,COALESCE(es.cpu_time,0) 
    + COALESCE(er.cpu_time,0) AS cpu
,COALESCE(es.reads,0) 
    + COALESCE(es.writes,0) 
    + COALESCE(er.reads,0) 
    + COALESCE(er.writes,0) AS physical_io
,COALESCE(er.open_transaction_count,-1) AS open_tran
,COALESCE(es.program_name,'') AS program_name
,es.login_time
FROM sys.dm_exec_sessions es
    LEFT OUTER JOIN sys.dm_exec_connections ec ON es.session_id = ec.session_id
    LEFT OUTER JOIN sys.dm_exec_requests er ON es.session_id = er.session_id
    LEFT OUTER JOIN sys.server_principals sp ON es.security_id = sp.sid
    LEFT OUTER JOIN sys.dm_os_tasks ota ON es.session_id = ota.session_id
    LEFT OUTER JOIN sys.dm_os_threads oth ON ota.worker_address = oth.worker_address
    CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS st
where es.is_user_process = 1 
  and es.session_id <> @@spid
ORDER BY es.session_id

end 
Run Code Online (Sandbox Code Playgroud)

通过显示spid正在等待的资源,下面的查询还可以显示在spid挂起时提供帮助的基本信息.

SELECT  wt.session_id, 
    ot.task_state, 
    wt.wait_type, 
    wt.wait_duration_ms, 
    wt.blocking_session_id, 
    wt.resource_description, 
    es.[host_name], 
    es.[program_name] 
FROM  sys.dm_os_waiting_tasks  wt  
INNER  JOIN sys.dm_os_tasks ot ON ot.task_address = wt.waiting_task_address 
INNER JOIN sys.dm_exec_sessions es ON es.session_id = wt.session_id 
WHERE es.is_user_process =  1 
Run Code Online (Sandbox Code Playgroud)

请以下面的图片为例:

在此输入图像描述

  • 感谢您提供非常有用的 SQL 代码段! (4认同)

ste*_*ary 13

我使用sp_whoIsActive来查看这类信息,因为它是一个现成的免费工具,可以为您提供有关慢速查询疑难解答的良好信息:

如何使用sp_WhoIsActive查找慢速SQL Server查询

通过这种方式,您可以获得查询文本,正在使用的计划,查询正在等待的资源,阻止它的内容,锁定它的内容以及更多内容.

比试图推出自己的要容易得多.