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):
-- Clear Wait Stats
DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);
GO
SELECT
[wait_type],
[wait_time_ms],
[signal_wait_time_ms]
FROM
sys.dm_os_wait_stats WITH (NOLOCK)
WHERE [wait_type] NOT IN (N'CLR_SEMAPHORE',N'LAZYWRITER_SLEEP',N'RESOURCE_QUEUE',N'SLEEP_TASK',
N'SLEEP_SYSTEMTASK',N'SQLTRACE_BUFFER_FLUSH',N'WAITFOR', N'LOGMGR_QUEUE',N'CHECKPOINT_QUEUE',
N'REQUEST_FOR_DEADLOCK_SEARCH',N'XE_TIMER_EVENT',N'BROKER_TO_FLUSH',N'BROKER_TASK_STOP',N'CLR_MANUAL_EVENT',
N'CLR_AUTO_EVENT',N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
N'XE_DISPATCHER_WAIT', N'XE_DISPATCHER_JOIN', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'ONDEMAND_TASK_QUEUE', N'BROKER_EVENTHANDLER', N'SLEEP_BPOOL_FLUSH')
ORDER BY
[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:
IF OBJECT_ID('tempdb..#waits') IS NOT NULL
DROP TABLE #waits;
CREATE TABLE #waits
(
[id] int,
[wait_type] varchar(128),
[wait_time_ms] bigint,
[signal_wait_time_ms] bigint
)
--collect initial wait data
INSERT INTO #waits
SELECT
1,
[wait_type],
[wait_time_ms],
[signal_wait_time_ms]
FROM
sys.dm_os_wait_stats WITH (NOLOCK)
WHERE [wait_type] NOT IN (N'CLR_SEMAPHORE',N'LAZYWRITER_SLEEP',N'RESOURCE_QUEUE',N'SLEEP_TASK',
N'SLEEP_SYSTEMTASK',N'SQLTRACE_BUFFER_FLUSH',N'WAITFOR', N'LOGMGR_QUEUE',N'CHECKPOINT_QUEUE',
N'REQUEST_FOR_DEADLOCK_SEARCH',N'XE_TIMER_EVENT',N'BROKER_TO_FLUSH',N'BROKER_TASK_STOP',N'CLR_MANUAL_EVENT',
N'CLR_AUTO_EVENT',N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
N'XE_DISPATCHER_WAIT', N'XE_DISPATCHER_JOIN', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'ONDEMAND_TASK_QUEUE', N'BROKER_EVENTHANDLER', N'SLEEP_BPOOL_FLUSH');
WAITFOR DELAY '00:00:01';
--second wait data
INSERT INTO #waits
SELECT
2,
[wait_type],
[wait_time_ms],
[signal_wait_time_ms]
FROM
sys.dm_os_wait_stats WITH (NOLOCK)
WHERE [wait_type] NOT IN (N'CLR_SEMAPHORE',N'LAZYWRITER_SLEEP',N'RESOURCE_QUEUE',N'SLEEP_TASK',
N'SLEEP_SYSTEMTASK',N'SQLTRACE_BUFFER_FLUSH',N'WAITFOR', N'LOGMGR_QUEUE',N'CHECKPOINT_QUEUE',
N'REQUEST_FOR_DEADLOCK_SEARCH',N'XE_TIMER_EVENT',N'BROKER_TO_FLUSH',N'BROKER_TASK_STOP',N'CLR_MANUAL_EVENT',
N'CLR_AUTO_EVENT',N'DISPATCHER_QUEUE_SEMAPHORE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
N'XE_DISPATCHER_WAIT', N'XE_DISPATCHER_JOIN', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'ONDEMAND_TASK_QUEUE', N'BROKER_EVENTHANDLER', N'SLEEP_BPOOL_FLUSH');
--Actual waits
WITH ActualWaits AS (
SELECT
A.[wait_type],
B.[wait_time_ms] - A.[wait_time_ms] AS [wait_time_ms],
B.[signal_wait_time_ms] - A.[signal_wait_time_ms] AS [signal_wait_time_ms]
FROM
#waits A
JOIN
#waits B ON A.[id] = B.[id] - 1 AND A.[wait_type] = B.[wait_type]
)
SELECT
[wait_type],
[wait_time_ms],
[signal_wait_time_ms]
FROM
ActualWaits
WHERE
[wait_time_ms] > 0
ORDER BY
[wait_time_ms] DESC
A második megoldás sokkal szimpatikusabb nekem.