Aktuális wait statisztika
Vannak olyan esetek, amikor kíváncsi vagyok a wait stat-ra. Ezt a sys.dm_os_wait_stats DMV-ből lehet kiszedni, igen ám, de ez az SQL Server legutóbbi indulása óta összegyűlt adatokat adja vissza. Ez azért lehet problémás, mert lehet nem is az összesre – indulástól eltelt idő alatt összesített, hanem az éppen akuális állapotra vagyok kíváncsi. Ezt két módon érhetem el:
- Kitörlöm a DMV-ből az adatokat és ezek után az új adatokat nézem meg (nem ajánlott):
1-- Clear Wait Stats
2DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);
3GO
4
5SELECT
6 [wait_type],
7 [wait_time_ms],
8 [signal_wait_time_ms]
9FROM
10 sys.dm_os_wait_stats WITH (NOLOCK)
11WHERE [wait_type] NOT IN (N'CLR_SEMAPHORE',N'LAZYWRITER_SLEEP',N'RESOURCE_QUEUE',N'SLEEP_TASK',
12 N'SLEEP_SYSTEMTASK',N'SQLTRACE_BUFFER_FLUSH',N'WAITFOR', N'LOGMGR_QUEUE',N'CHECKPOINT_QUEUE',
13 N'REQUEST_FOR_DEADLOCK_SEARCH',N'XE_TIMER_EVENT',N'BROKER_TO_FLUSH',N'BROKER_TASK_STOP',N'CLR_MANUAL_EVENT',
14 N'CLR_AUTO_EVENT',N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
15 N'XE_DISPATCHER_WAIT', N'XE_DISPATCHER_JOIN', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
16 N'ONDEMAND_TASK_QUEUE', N'BROKER_EVENTHANDLER', N'SLEEP_BPOOL_FLUSH')
17ORDER BY
18 [wait_time_ms] DESC
- A második megoldás során nem törlök – nem is szeretem azt a megoldást –, hanem lekérdezem az akuális összesített adatot, majd x másodperc múlva ismét, ezek után veszem a különbséget. Az alábbi példa 1 másodperces késleltetést használ:
1IF OBJECT_ID('tempdb..#waits') IS NOT NULL
2 DROP TABLE #waits;
3
4CREATE TABLE #waits
5(
6 [id] int,
7 [wait_type] varchar(128),
8 [wait_time_ms] bigint,
9 [signal_wait_time_ms] bigint
10)
11
12--collect initial wait data
13INSERT INTO #waits
14SELECT
15 1,
16 [wait_type],
17 [wait_time_ms],
18 [signal_wait_time_ms]
19FROM
20 sys.dm_os_wait_stats WITH (NOLOCK)
21WHERE [wait_type] NOT IN (N'CLR_SEMAPHORE',N'LAZYWRITER_SLEEP',N'RESOURCE_QUEUE',N'SLEEP_TASK',
22 N'SLEEP_SYSTEMTASK',N'SQLTRACE_BUFFER_FLUSH',N'WAITFOR', N'LOGMGR_QUEUE',N'CHECKPOINT_QUEUE',
23 N'REQUEST_FOR_DEADLOCK_SEARCH',N'XE_TIMER_EVENT',N'BROKER_TO_FLUSH',N'BROKER_TASK_STOP',N'CLR_MANUAL_EVENT',
24 N'CLR_AUTO_EVENT',N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
25 N'XE_DISPATCHER_WAIT', N'XE_DISPATCHER_JOIN', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
26 N'ONDEMAND_TASK_QUEUE', N'BROKER_EVENTHANDLER', N'SLEEP_BPOOL_FLUSH');
27
28WAITFOR DELAY '00:00:01';
29--second wait data
30INSERT INTO #waits
31SELECT
32 2,
33 [wait_type],
34 [wait_time_ms],
35 [signal_wait_time_ms]
36FROM
37 sys.dm_os_wait_stats WITH (NOLOCK)
38WHERE [wait_type] NOT IN (N'CLR_SEMAPHORE',N'LAZYWRITER_SLEEP',N'RESOURCE_QUEUE',N'SLEEP_TASK',
39 N'SLEEP_SYSTEMTASK',N'SQLTRACE_BUFFER_FLUSH',N'WAITFOR', N'LOGMGR_QUEUE',N'CHECKPOINT_QUEUE',
40 N'REQUEST_FOR_DEADLOCK_SEARCH',N'XE_TIMER_EVENT',N'BROKER_TO_FLUSH',N'BROKER_TASK_STOP',N'CLR_MANUAL_EVENT',
41 N'CLR_AUTO_EVENT',N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
42 N'XE_DISPATCHER_WAIT', N'XE_DISPATCHER_JOIN', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
43 N'ONDEMAND_TASK_QUEUE', N'BROKER_EVENTHANDLER', N'SLEEP_BPOOL_FLUSH');
44
45--Actual waits
46WITH ActualWaits AS (
47SELECT
48 A.[wait_type],
49 B.[wait_time_ms] - A.[wait_time_ms] AS [wait_time_ms],
50 B.[signal_wait_time_ms] - A.[signal_wait_time_ms] AS [signal_wait_time_ms]
51FROM
52 #waits A
53JOIN
54 #waits B ON A.[id] = B.[id] - 1 AND A.[wait_type] = B.[wait_type]
55)
56
57SELECT
58 [wait_type],
59 [wait_time_ms],
60 [signal_wait_time_ms]
61FROM
62 ActualWaits
63WHERE
64 [wait_time_ms] > 0
65ORDER BY
66 [wait_time_ms] DESC
A második megoldás sokkal szimpatikusabb nekem.