SQL Server の CPU 使用率を取得する場合、パフォーマンスモニターや Workload Group Stats の情報を使用して、情報の取得を行うことがあります。
パフォーマンスモニターについては、OS 周りの権限が付与されていない (RDS等) 場合は使用することができません。
Workload Group Stats については、Enterprise Edition であれば、Default Pool 等の Internal 以外の Pool の情報を取得することで活用することができますが、Standard Edition では、リソースガバナーが使用できないため、Pool 単位の情報を取得することができません。
また、上記の情報は「現在の値」を取得するため、事前にメトリクスの取得を設定しておかないと、確認できないという課題もあります。
Standard Edition や直近、数時間で構わないので、過去にさかのぼって CPU の使用率を取得する場合、リングバッファーの情報を活用するという方法を使用することができます。
SQL Database では、想定している情報が取得できないようですが、SQL Server であれば、2012 以降では動いていると思いますので、その方法を。
方法としては、Azure Data Studio の Server Report という拡張機能で使用されている方法になります。
この拡張機能では、CPU 使用率の取得が行われているのですが、これには、次のようなクエリの実行が行われています。
-- https://github.com/Microsoft/azuredatastudio/tree/master/samples/serverReports DECLARE @ts_now BIGINT = ( SELECT cpu_ticks / (cpu_ticks / ms_ticks) FROM sys.dm_os_sys_info ); SELECT TOP (100) 'CPU%' AS [label] , DATEADD(ms, - 1 * (@ts_now - [timestamp]), GETDATE()) AS [Event Time] , SQLProcessUtilization AS [SQL Server Process CPU Utilization] , SystemIdle AS [System Idle Process] , 100 - SystemIdle - SQLProcessUtilization AS [Other Process CPU Utilization] FROM ( SELECT record.value('(./Record/@id)[1]', 'int') AS record_id , record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') AS [SystemIdle] , record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') AS [SQLProcessUtilization] , [timestamp] FROM ( SELECT [timestamp] , convert(XML, record) AS [record] FROM sys.dm_os_ring_buffers WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' AND record LIKE '%<systemHealth>%' ) AS x ) AS y --ORDER BY record_id DESC; ORDER BY [Event Time] DESC; GO
リングバッファー内に保持されている CPU 使用率を加工して出力しているクエリとなります。
間隔としては 1 分間隔で取得されている情報ですが、256 個の情報が格納されていそうですので、「過去 (4 時間程度) にさかのぼって直近の CPU 使用率の情報を取得したい」というようなことがあった場合、メトリクスの取得の仕組みを設定していなくても汎用的に使用することができる方法となります。
CPU 使用率の調査をするときに、とっさに使用するクエリとして覚えておくと便利ではないでしょうか。
もちろん、クエリを覚えておかず、Azure Data Studio を起動するだけでも、拡張機能がインストールされていれば使用できますので、Azure Data Studio を活用することでもよいかと。