Jak czasy oczekiwania mogą być wyższe niż czas zegara?

15

Kiedy śledzę oczekiwania za pomocą sp_BlitzFirst, otrzymuję ten szczegół:

<?ClickToSeeDetails -- 
For 20 seconds over the last 5 seconds, SQL Server was waiting on this 
particular bottleneck.


 -- ?>

Czy to powinno brzmieć „20 razy w ciągu ostatnich 5 sekund?” Znalezienie było CLR_SEMAPHORE.

Robert Rice
źródło

Odpowiedzi:

24

Statystyki braku oczekiwania mogą (i częściej będą) sumować więcej niż fizyczny czas poświęcony samemu serwerowi.

Wyobraź sobie sytuację, w której 2 oddzielne wątki spędzają tę samą sekundę na oczekiwaniu na jakiś zasób - miałbyś 2 sekundy czasu oczekiwania na 1 sekundę czasu zegara.

Każdy wątek ma swoje własne oczekiwania - komunikat mówi, że 20 sekund czasu oczekiwania na ten konkretny zasób wystąpiło w ciągu ostatnich 5 sekund czasu zegarowego.

Innymi słowy, każdy rdzeń może uruchamiać wiele zapytań w tym samym czasie, a wiele rdzeni może dawać jeszcze więcej oczekiwań. To znaczy, że jednostka jest naprawdę wątkiem · sekund, a nie sekund.

George.Palacios
źródło
8

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 RUNNINGmogą 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 RUNNABLEmogą 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_YIELDczas oczekiwania.

Pracownicy ze stanem SUSPENDEDmogą 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.

Joe Obbish
źródło