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 RUNNING
kö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 RUNNABLE
kö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_YIELD
Wartezeit ansammeln .
Arbeiter mit einem Status von SUSPENDED
kö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.