Potrebbe anche essere utile elaborare un esempio. Considera i tre stati più comuni per un lavoratore :
IN FUNZIONE = Il lavoratore è attualmente in esecuzione in modo non preventivo o preventivo.
RUNNABLE = Il lavoratore è pronto per essere eseguito sullo scheduler.
SOSPESO = Il lavoratore è attualmente sospeso, in attesa che un evento gli invii un segnale.
I lavoratori con uno stato di RUNNING
possono generare tempi di attesa. Ad esempio, se il lavoratore deve eseguire il codice nel sistema operativo anziché in SQLOS, può inserire un'attesa preventiva o esterna. Durante quel periodo eseguirà il codice sulla CPU associata ma genererà comunque tempi di attesa.
Lavoratori con uno stato di RUNNABLE
possono generare tempi di attesa (per quanto ne so lo fanno sempre). Se al lavoratore è stato segnalato che una risorsa era disponibile, potrebbe accumulare il tempo di attesa del segnale in base all'ultima attesa. Se il lavoratore ha esaurito il suo precedente quantum di 4 ms, potrebbe accumulare SOS_SCHEDULER_YIELD
tempo di attesa.
Lavoratori con uno stato di SUSPENDED
possono generare tempi di attesa. Considera un lavoratore che sta aspettando un lucchetto. Genererà tempo di attesa fino a quando viene segnalato che la risorsa di blocco di cui ha bisogno è disponibile. Alcuni lavoratori sospesi non generano tempi di attesa, inclusi quelli non associati a un'attività.
Il mio desktop ha quattro core logici, quindi il conteggio massimo dei lavoratori predefinito è 512 . È quasi certamente poco pratico, ma su questa macchina potrei teoricamente generare 512 secondi di tempo di attesa al secondo se riuscissi a far aspettare ogni lavoratore su qualcosa contemporaneamente. Con l'aumentare del numero di core / lavoratore, tale numero può aumentare ulteriormente.
Puoi vedere più di un secondo di attese al secondo anche se non stai eseguendo alcuna query su SQL Server. Sul mio computer, la seguente query sembra generare tra 9-14 righe:
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;
Posso fare un'istantanea del tempo di attesa totale dall'ultimo riavvio del server e confrontarlo con un nuovo totale dopo aver atteso dieci secondi:
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 volte la matematica risolve. L'ultima volta che l'ho eseguito il delta è stato 101339 ms. In altre parole, ho avuto oltre 10 secondi di attese al secondo solo dalle attività di sistema.