También podría ser útil trabajar con un ejemplo. Considere los tres estados más comunes para un trabajador :
EN EJECUCIÓN = El trabajador se está ejecutando actualmente de forma no preventiva o preventiva.
RUNNABLE = El trabajador está listo para ejecutarse en el planificador.
SUSPENDIDO = El trabajador está suspendido actualmente, esperando que un evento le envíe una señal.
Los trabajadores con un estado de RUNNING
pueden generar tiempo de espera. Por ejemplo, si el trabajador necesita ejecutar código en el sistema operativo en lugar de en SQLOS, entonces puede ingresar una espera preventiva o externa. Durante ese tiempo, ejecutará código en su CPU asociada, pero seguirá generando tiempo de espera.
Los trabajadores con un estado de RUNNABLE
pueden generar tiempo de espera (que yo sepa, siempre lo hacen). Si se indicó al trabajador que había un recurso disponible, puede acumular tiempo de espera de la señal en función de la última espera. Si el trabajador agotó su cuántica anterior de 4 ms, entonces puede acumular SOS_SCHEDULER_YIELD
tiempo de espera.
Los trabajadores con un estado de SUSPENDED
pueden generar tiempo de espera. Considere un trabajador que está esperando una cerradura. Generará tiempo de espera hasta que se indique que el recurso de bloqueo que necesita está disponible. Algunos trabajadores suspendidos no generan tiempo de espera, incluidos los que no están asociados con una tarea.
Mi escritorio tiene cuatro núcleos lógicos, por lo que el conteo máximo de trabajadores predeterminado es 512 . Es casi seguro que no es práctico, pero en esta máquina, en teoría, podría generar 512 segundos de tiempo de espera por segundo si lograra que cada trabajador espere algo a la vez. A medida que aumentan los recuentos de núcleos / trabajadores, ese número puede ser aún mayor.
Puede ver más de un segundo de esperas por segundo, incluso si no está ejecutando ninguna consulta en SQL Server. En mi máquina, la siguiente consulta parece generar entre 9-14 filas:
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;
Puedo tomar una instantánea del tiempo de espera total desde la última vez que reinicié el servidor y compararlo con un nuevo total después de esperar diez segundos:
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';
A veces las matemáticas funcionan. La última vez que lo ejecuté, el delta fue de 101339 ms. En otras palabras, tuve más de 10 segundos de espera por segundo solo de las tareas del sistema.