Wie können Wartezeiten höher als die Uhrzeit sein?

15

Wenn ich mit sp_BlitzFirst Warten nachverfolge, erhalte ich folgendes Detail:

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


 -- ?>

Sollte dies "20 Mal in den letzten 5 Sekunden" lauten? Das Finden war CLR_SEMAPHORE.

Robert Rice
quelle

Antworten:

24

Nein - Wartestatistiken können (und werden in den meisten Fällen) mehr als die für den Server selbst aufgewendete physische Zeit summieren.

Stellen Sie sich eine Situation vor, in der zwei separate Threads dieselbe Sekunde damit verbringen, auf eine Ressource zu warten - Sie haben 2 Sekunden Wartezeit für 1 Sekunde der Uhrzeit.

Jeder Thread hat seine eigenen Wartezeiten. In der Nachricht wird angegeben, dass in den letzten 5 Sekunden der Uhrzeit 20 Sekunden auf diese bestimmte Ressource gewartet wurde.

Anders ausgedrückt, auf jedem Kern können mehrere Abfragen gleichzeitig ausgeführt werden, und mehrere Kerne können zu noch mehr Wartezeiten führen. Das heißt, die Einheit ist wirklich Thread-Sekunden, nicht Sekunden.

George.Palacios
quelle
8

Es kann auch hilfreich sein, ein Beispiel durchzuarbeiten. Betrachten Sie die drei häufigsten Zustände eines Arbeitnehmers :

RUNNING = Der Worker wird derzeit entweder nicht oder nur vorübergehend ausgeführt.

RUNNABLE = Der Worker ist bereit, auf dem Scheduler ausgeführt zu werden.

SUSPENDED = Der Worker ist momentan suspendiert und wartet auf ein Ereignis, um ihm ein Signal zu senden.

Arbeiter mit einem Status von RUNNINGkönnen Wartezeiten erzeugen. Wenn der Worker beispielsweise Code nicht in SQLOS, sondern im Betriebssystem ausführen muss, tritt möglicherweise eine vorbeugende oder externe Wartezeit ein. Während dieser Zeit wird Code auf der zugeordneten CPU ausgeführt, es wird jedoch weiterhin Wartezeit generiert.

Arbeitnehmer mit einem Status von RUNNABLEkönnen Wartezeiten erzeugen (soweit ich weiß, dass dies immer der Fall ist). Wenn dem Mitarbeiter signalisiert wurde, dass eine Ressource verfügbar ist, kann sich die Signalwartezeit basierend auf der letzten Wartezeit ansammeln. Wenn der Arbeiter sein vorheriges 4 ms-Quantum erschöpft hat, kann sich SOS_SCHEDULER_YIELDWartezeit ansammeln .

Arbeiter mit einem Status von SUSPENDEDkönnen Wartezeiten erzeugen. Stellen Sie sich einen Arbeiter vor, der auf eine Sperre wartet. Es wird eine Wartezeit generiert, bis signalisiert wird, dass die benötigte Sperrressource verfügbar ist. Einige suspendierte Mitarbeiter verursachen keine Wartezeiten, auch solche, die keiner Aufgabe zugeordnet sind.

Mein Desktop verfügt über vier logische Kerne, daher beträgt die Standardanzahl der Worker 512 . Es ist mit ziemlicher Sicherheit unpraktisch, aber auf dieser Maschine könnte ich theoretisch 512 Sekunden Wartezeit pro Sekunde erzeugen, wenn ich es schaffe, jeden Arbeiter auf einmal auf etwas warten zu lassen. Wenn die Anzahl der Mitarbeiter steigt, kann diese Anzahl sogar noch höher werden.

Sie können mehr als eine Sekunde Wartezeit pro Sekunde sehen, auch wenn Sie keine Abfragen für SQL Server ausführen. Auf meinem Computer scheint die folgende Abfrage zwischen 9 und 14 Zeilen zu generieren:

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;

Ich kann eine Momentaufnahme der gesamten Wartezeit seit dem letzten Neustart des Servers machen und diese nach zehn Sekunden Wartezeit mit einer neuen Summe vergleichen:

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';

Manchmal klappt die Mathematik. Das letzte Mal, als ich es lief, war das Delta 101339 ms. Mit anderen Worten, ich hatte über 10 Sekunden Wartezeit pro Sekunde, nur aufgrund von Systemaufgaben.

Joe Obbish
quelle