Answers:
通过示例工作可能也会有所帮助。考虑工人的三种最常见状态:
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秒的等待时间。