Pomocne może być również przejrzenie przykładu. Rozważ trzy najczęstsze stany dla pracownika :
RUNNING = Pracownik obecnie działa albo zapobiegawczo, albo zapobiegawczo.
RUNNABLE = Pracownik jest gotowy do uruchomienia w harmonogramie.
SUSPENDED = Pracownik jest obecnie zawieszony i czeka na zdarzenie, aby wysłać mu sygnał.
Pracownicy ze stanem RUNNING
mogą generować czas oczekiwania. Na przykład, jeśli pracownik musi uruchamiać kod w systemie operacyjnym zamiast w SQLOS, może wprowadzić oczekiwanie wyprzedzające lub zewnętrzne. W tym czasie będzie działał kod na powiązanym procesorze, ale nadal będzie generował czas oczekiwania.
Pracownicy ze stanem RUNNABLE
mogą generować czas oczekiwania (o ile wiem, że zawsze tak robią). Jeśli pracownik został zasygnalizowany, że zasób jest dostępny, może on skumulować czas oczekiwania na sygnał na podstawie ostatniego oczekiwania. Jeśli pracownik wyczerpał swoje poprzednie 4 ms kwantowe, może skumulować SOS_SCHEDULER_YIELD
czas oczekiwania.
Pracownicy ze stanem SUSPENDED
mogą generować czas oczekiwania. Zastanów się nad pracownikiem, który czeka na zamek. Będzie generować czas oczekiwania, aż zostanie zasygnalizowane, że zasób blokady, którego potrzebuje, jest dostępny. Niektórzy zawieszeni pracownicy nie generują czasu oczekiwania, w tym osoby niezwiązane z zadaniem.
Mój pulpit ma cztery rdzenie logiczne, więc domyślna maksymalna liczba pracowników to 512 . Jest to prawie na pewno niepraktyczne, ale na tym komputerze teoretycznie mógłbym wygenerować 512 sekund czasu oczekiwania na sekundę, jeśli udało mi się zmusić każdego pracownika do oczekiwania na coś na raz. Wraz ze wzrostem liczby rdzeni / pracowników liczba ta może być jeszcze wyższa.
Możesz zobaczyć więcej niż jedną sekundę oczekiwania na sekundę, nawet jeśli nie uruchamiasz żadnych zapytań przeciwko SQL Serverowi. Na moim komputerze wydaje się, że następujące zapytanie generuje od 9-14 wierszy:
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;
Mogę zrobić migawkę całkowitego czasu oczekiwania od ostatniego uruchomienia serwera i porównać go z nową sumą po odczekaniu dziesięciu sekund:
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';
Czasami matematyka się sprawdza. Ostatnim razem, gdy go uruchomiłem, delta wynosiła 101339 ms. Innymi słowy, miałem ponad 10 sekund oczekiwania na sekundę tylko z zadań systemowych.