当我在会话 #1 中创建测试用例时:
create table ##t (a int)
begin tran
insert into ##t select 1
在另一个会话 #2 中运行
select * from ##t
在另一个会话中运行
sp_who2 active
那么在阻塞的会话#2 上没有 CPU 和 IO 计数器增加。这是有道理的,但是阻塞语句总是这样吗?
当我在会话 #1 中创建测试用例时:
create table ##t (a int)
begin tran
insert into ##t select 1
在另一个会话 #2 中运行
select * from ##t
在另一个会话中运行
sp_who2 active
那么在阻塞的会话#2 上没有 CPU 和 IO 计数器增加。这是有道理的,但是阻塞语句总是这样吗?
这里的答案是“这取决于” - 虽然实际上被阻止了?会话不应使用任何资源。它处于一种状态,基本上是在说“我当然想做我的工作,嘿 SQL Server 我可以锁定某某资源”所以当该资源被锁定时 - 会话基本上无法做任何事情,除了等待资源可用性。一旦被清除,它就可以开始运行或加入可运行队列等待其调度程序时间。
现在您仍然可以看到 IO 和 CPU 在会话中增加,其中有许多查询或步骤在不同位置被阻塞。所以你可以查看并看到它当前被阻塞,但看到 CPU 增加或 IO - 那是因为它经过一个块为语句做了一些工作但随后再次被阻塞。
我通常会使用显示会话的查询持续时间和 CPU/IO 指标的工具来诊断阻塞,但如果查询的执行时间高于正常持续时间但仍保持在 CPU 和 IO 的正常限制内,则可能会错过跟踪块。不仅阻塞会以这种方式呈现,而且经常如此 - 因此它成为一种工具,可以说“嘿,让我们看看我们是否看到任何阻塞”。
我可能还建议您看看sp_whoisactive。一个很棒的脚本,它将比 SP_Who2 提供更多信息。