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):
-- 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.

Add comment