Также может быть полезно проработать пример. Рассмотрим три наиболее распространенных состояния для работника :
RUNNING = Работник в настоящее время работает либо без вытеснения, либо с вытеснением.
RUNNABLE = Рабочий готов к запуску в планировщике.
SUSPENDED = Работник в настоящее время приостановлен, ожидая события, чтобы отправить ему сигнал.
Работники с состоянием RUNNING
могут генерировать время ожидания. Например, если рабочий должен запустить код в ОС, а не в SQLOS, он может ввести упреждающее или внешнее ожидание. В течение этого времени он будет выполнять код на связанном с ним процессоре, но все равно будет генерировать время ожидания.
Работники с состоянием 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 секунд ожидания в секунду только от системных задач.