等待时间如何比时钟时间高?


15

当我使用sp_BlitzFirst跟踪等待时,我得到以下详细信息:

<?ClickToSeeDetails -- 
For 20 seconds over the last 5 seconds, SQL Server was waiting on this 
particular bottleneck.


 -- ?>

那应该是“过去5秒内20次?” 发现是CLR_SEMAPHORE。

Answers:


24

否-等待统计信息可以(而且通常会比)花费在服务器本身上的物理时间更多。

想象一下这样一种情况:两个单独的线程花相同的时间等待某种资源-您将有2秒的等待时间,即1秒的时钟时间。

每个线程都有自己的等待-消息告诉您,特定资源的20秒等待时间在时钟时间的最后5秒内发生。

换句话说,每个内核可以同时运行多个查询,并且多个内核加起来的等待次数甚至更多。也就是说,单位实际上是线程·秒,而不是秒。


8

通过示例工作可能也会有所帮助。考虑工人的三种最常见状态:

RUNNING = Worker当前正在非抢先或抢先运行。

RUNNABLE =工作程序已准备好在调度程序上运行。

SUSPENDED =该工人当前处于暂停状态,正在等待事件向其发送信号。

状态为的工人RUNNING可以产生等待时间。例如,如果工作人员需要在OS中而不是在SQLOS中运行代码,则它可能会进入抢占式等待或外部等待。在此期间,它将在其关联的CPU上运行代码,但仍会产生等待时间。

状态为的工人RUNNABLE可以产生等待时间(据我所知,他们总是如此)。如果通知工作人员资源可用,则它可能根据上一次等待来累积信号等待时间。如果工人用尽了之前的4毫秒量,则可能会累积SOS_SCHEDULER_YIELD等待时间。

状态为 SUSPENDED可以产生等待时间。考虑一个正在等待锁的工人。它将生成等待时间,直到发出信号表明所需的锁定资源可用为止。一些暂停的工人不会产生等待时间,包括那些与任务无关的时间。

我的桌面有四个逻辑核心,因此默认的最大工作程序计数为512。几乎可以肯定,这是不切实际的,但是在理论上,如果我设法让每个工人一次等待某件事,那么我每秒可以产生512秒的等待时间。随着核心/工人人数的增加,这个数字可能会更高。

即使您没有针对SQL Server运行任何查询,您也可以看到每秒超过一秒钟的等待时间。在我的机器上,以下查询似乎在9-14行之间生成:

SELECT [state], last_wait_type, wait_started_ms_ticks
FROM sys.dm_os_workers
WHERE [state] IN ('SUSPENDED', 'RUNNABLE')
AND task_address IS NOT NULL
AND wait_started_ms_ticks <> 0
AND wait_started_ms_ticks >= start_quantum;

自上次重新启动服务器以来,我可以拍摄总等待时间的快照,并在等待十秒钟后将其与新的总时间进行比较:

DECLARE @start_wait_time_ms BIGINT;

SELECT @start_wait_time_ms = SUM(wait_time_ms)
FROM sys.dm_os_wait_stats
WHERE wait_type <> 'WAITFOR';

WAITFOR DELAY '00:00:10';

SELECT SUM(wait_time_ms) - @start_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type <> 'WAITFOR';

有时数学会得出结果。我上次运行该增量的时间是101339毫秒。换句话说,仅系统任务我每秒就有超过10秒的等待时间。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.