以前、待ち事象を時系列で解析するためのデータを取得する という投稿をしたのですがその別バージョンとなります。
以前の投稿は、定期的の wait_stats を取得していましたが、取得したタイミングの情報をそのまま格納していたため、右肩上がりの情報しか作成することができませんでした。
そこで以下のようなクエリを作成し、前回実行時との差分を求めてテーブルに格納する仕組みにしてみました。
SET NOCOUNT ON GO DECLARE @waittime nvarchar(8) = '00:00:10' DECLARE @initilalize bit = 0 IF OBJECT_ID('tempdb..#tmp_wait_stats_old') IS NULL BEGIN SELECT * INTO #tmp_wait_stats_old FROM sys.dm_os_wait_stats CREATE CLUSTERED INDEX IX_tmp_wait_stats_old ON #tmp_wait_stats_old (wait_type) END ELSE BEGIN Truncate Table #tmp_wait_stats_old END IF OBJECT_ID('tempdb..#tmp_wait_stats') IS NULL BEGIN SELECT GETDATE() AS DateTime, wait_type, waiting_tasks_count, wait_time_ms, max_wait_time_ms, signal_wait_time_ms INTO #tmp_wait_stats FROM sys.dm_os_wait_stats WHERE 1 = 0 CREATE CLUSTERED INDEX IX_tmp_wait_stats ON #tmp_wait_stats (wait_type) END ELSE BEGIN IF @initilalize = 1 Truncate Table #tmp_wait_stats END WHILE (1=1) BEGIN INSERT INTO #tmp_wait_stats SELECT GETDATE() AS DateTime, T1.wait_type, ISNULL(T1.waiting_tasks_count - T2.waiting_tasks_count, 0) AS waiting_tasks_count, ISNULL(T1.wait_time_ms - T2.wait_time_ms, 0) AS wait_time_ms, ISNULL(T1.max_wait_time_ms - T2.max_wait_time_ms, 0) AS max_wait_time_ms, ISNULL(T1.signal_wait_time_ms - T2.signal_wait_time_ms, 0) AS signal_wait_time_ms FROM sys.dm_os_wait_stats T1 LEFT JOIN #tmp_wait_stats_old T2 ON T1.wait_type = T2.wait_type ORDER BY T1.wait_type ASC TRUNCATE TABLE #tmp_wait_stats_old INSERT INTO #tmp_wait_stats_old SELECT * FROM sys.dm_os_wait_stats EXEC ('WAITFOR DELAY ''' + @waittime + '''') END
実行結果は、[#tmp_wait_stats] に格納されますので、実行後にこのテーブルを検索することで情報を確認することができます。
上記のクエリで 10 秒間隔で情報を取得している間に以下のクエリを SQLQueryStress で実行してみます。
SET NOCOUNT ON DECLARE @delay int = (SELECT RAND() * 10) EXEC ('WAITFOR DELAY ''00:00:' + @delay + '''') WAITFOR DELAY '00:00:01'
以下は [WAITFOR] 待ち事象の情報を取得したものですが、このようなグラフを作成することができます。
格納先の一時テーブルを作成しない場合は以下のようなクエリでしょうか。
# 結果をファイルに保存して履歴を取得する必要がありますが。
SET NOCOUNT ON GO DECLARE @waittime nvarchar(8) = '00:00:10' IF OBJECT_ID('tempdb..#tmp_wait_stats_old') IS NULL BEGIN SELECT * INTO #tmp_wait_stats_old FROM sys.dm_os_wait_stats CREATE CLUSTERED INDEX IX_tmp_wait_stats_old ON #tmp_wait_stats_old (wait_type) END ELSE BEGIN Truncate Table #tmp_wait_stats_old END WHILE (1=1) BEGIN SELECT GETDATE() AS DateTime, T1.wait_type, ISNULL(T1.waiting_tasks_count - T2.waiting_tasks_count, 0) AS waiting_tasks_count, ISNULL(T1.wait_time_ms - T2.wait_time_ms, 0) AS wait_time_ms, ISNULL(T1.max_wait_time_ms - T2.max_wait_time_ms, 0) AS max_wait_time_ms, ISNULL(T1.signal_wait_time_ms - T2.signal_wait_time_ms, 0) AS signal_wait_time_ms FROM sys.dm_os_wait_stats T1 LEFT JOIN #tmp_wait_stats_old T2 ON T1.wait_type = T2.wait_type ORDER BY T1.wait_type ASC TRUNCATE TABLE #tmp_wait_stats_old INSERT INTO #tmp_wait_stats_old SELECT * FROM sys.dm_os_wait_stats EXEC ('WAITFOR DELAY ''' + @waittime + '''') END
今までは 2 点の差分しか出していなかったのですが、いろいろな確認方法を持っていたいなと。