SQL Serverで前年同月のI/O負荷とパフォーマンスを比較する方法|Query StoreとDMVで実践する月次分析

「2023年4月」と「2024年4月」のように、異なる年の同じ月で SQL Server の I/O 負荷や応答性能を比較できると、ピーク期の変化やチューニング効果、システム増強の必要性を定量的に判断できます。この記事では、Query Store・DMV・Extended Events・PerfMon・サードパーティ製ツールなどを組み合わせ、前年同月比で SQL Server の負荷を可視化する実践的な方法を紹介します。

目次

SQL Serverで「前年同月」を比較するべき理由

「今年の4月は遅い気がする」「去年より I/O 負荷が増えているのでは?」という感覚だけでは、ハードウェア増強やアーキテクチャ変更の判断はできません。特に業務システムでは、月末締め・セール期間など、負荷が季節要因に強く引きずられることが多く、単純な「先月比」では傾向を正しく捉えにくくなります。

そのため、SQL Server の長期運用では、次のような観点で「前年同月比」を見ることが重要です。

  • ビジネスイベントが同じ条件になりやすい(決算期、セール、キャンペーンなど)
  • 季節要因を除いた純粋な成長・負荷増加を見やすい
  • 昨年のチューニングやインフラ増強の効果検証ができる
  • 来期以降のキャパシティプランニングに活かせる

この記事では、たとえば「2023年4月」と「2024年4月」を比較することを例に、実際のスクリプトと運用パターンを交えながら解説します。

比較前に決めておくべき指標と前提条件

闇雲にメトリクスを集めても、後から「結局どれを見ればいいの?」となりがちです。まずは次の3点を決めてから収集・分析に進みましょう。

どの指標を比較するか

カテゴリ代表的な指標主な用途
I/O 負荷logical_reads, physical_reads, read/write bytes, Disk Reads/sec, Disk Writes/secストレージ負荷の傾向把握、I/O ボトルネックの疑い
応答性能クエリ実行時間、平均/最大 Duration、CPU 時間ユーザー体感速度やバッチ処理時間の変化
スループットBatch Requests/sec、トランザクション数処理量の増加が原因か、遅延が原因かを切り分け
待機統計PAGEIOLATCH_*, WRITELOG, CXPACKET, ASYNC_NETWORK_IO などI/O 起因なのか、別要因なのかを特定する手掛かり
リソース使用率CPU 使用率、メモリ使用量、ディスクキュー長インフラ増強が必要か、設計やクエリ見直しで解決できるかを判断

どの粒度で比較するか

  • 月トータル:ざっくり増減傾向を把握する(前年同月比で○○%増など)
  • 日別:月末・締め日前後など、ピークの位置と大きさを比較
  • 時間帯別:バッチ時間帯・オンライン時間帯で分けて分析

最初は「月トータル」と「ピーク日」の2パターンだけ決めておくと、設計がシンプルになります。

どのレイヤーのデータを使うか

SQL Server で長期比較を行う代表的な手段は次の通りです。

項目主な機能・使いどころポイント・補足
Query Store(SQL Server 2016 以降)クエリごとの CPU 時間・実行回数・I/O 量を時系列で保持期間を絞って集計すれば月次比較が可能。DB 単位なので複数 DB の場合は集計用スクリプトや PowerShell で統合すると便利。
DMV/DMFsys.dm_io_virtual_file_stats や sys.dm_exec_query_stats など、累積カウンタを取得定期的にスナップショットを取得し、差分を計算することで「その期間の負荷」を算出。SQL Agent ジョブで自動化するのが一般的。
Extended Events待機事象や I/O 発生量を細かく捕捉し、ファイルへ記録高精度だがログ量が多くなりやすい。対象クエリやイベント、期間をしっかり絞ることが重要。
Performance Monitor (PerfMon)OS/SQL のカウンタ(Disk Reads/sec, Batch Requests/sec など)を長期収集Windows のデータコレクタセットで CSV 出力し、Excel Power Pivot や Power BI で前年同月を比較すると分かりやすい。
Activity Monitor / SSMS 組み込みレポート直近の負荷確認・簡易トレンドの可視化リアルタイム診断向き。履歴を残さないため、月間比較には向かない(スクリーンショットや手動エクスポートが必要)。
Data Collector(Management Data Warehouse)SQL Server 標準の長期監視基盤GUI は古いが、追加コンポーネント不要で中央 DB に履歴が残る。既存環境であればコストゼロで利用可能。
サードパーティ監視ツールSolarWinds DPA/DPM、Redgate SQL Monitor、Quest Foglight/Spotlight、SentryOne、dbForge Monitor など導入後自動的に履歴を蓄積し、GUI で日・週・月をドラッグするだけで比較レポートを表示可能。評価版で比較検証するのがおすすめ。
SCOM + SQL Management PackMicrosoft 純正の統合監視基盤既に SCOM を運用している企業なら、SQL MP の追加で SQL Server 監視を統合できる。

この中でも、短期的な比較なら Query Store、長期的なサーバ全体の傾向把握には DMV スナップショット+PerfMon という組み合わせが理解しやすく、導入しやすいパターンです。

Query Storeでクエリ単位の前年同月比較を行う

Query Storeの前提と設定確認

Query Store は SQL Server 2016 以降(および Azure SQL 系)で利用できる機能で、クエリの実行統計とプラン情報をデータベース内に保存します。まず、比較したいデータベースで Query Store が有効になっているか確認します。

ALTER DATABASE YourDB
SET QUERY_STORE = ON;

保持期間(CLEANUP_POLICY)やキャプチャモード(READ_WRITE、AUTO)も、少なくとも比較対象期間をカバーできるように設定しておきます。既に運用中であれば、保持期間が短すぎて昨年分が消えていないかもチェックしましょう。

Query Storeから特定期間の負荷を集計する例

以下は、2023年4月と2024年4月のクエリごとの I/O・CPU・実行回数を集計し、前年同月比を比較する T-SQL の一例です(1データベース内想定)。

DECLARE @from1 DATETIME2 = '2023-04-01 00:00:00';
DECLARE @to1   DATETIME2 = '2023-05-01 00:00:00';
DECLARE @from2 DATETIME2 = '2024-04-01 00:00:00';
DECLARE @to2   DATETIME2 = '2024-05-01 00:00:00';

;WITH qs AS (
    SELECT
        period = CASE
                    WHEN rs_interval.start_time >= @from1 AND rs_interval.start_time < @to1 THEN '2023-04'
                    WHEN rs_interval.start_time >= @from2 AND rs_interval.start_time < @to2 THEN '2024-04'
                 END,
        qt.query_sql_text,
        rs.count_executions,
        rs.avg_duration,         -- 単位はマイクロ秒
        rs.avg_cpu_time,         -- 単位はマイクロ秒
        rs.avg_logical_io_reads,
        rs.avg_logical_io_writes,
        rs.avg_physical_io_reads
    FROM sys.query_store_runtime_stats AS rs
    JOIN sys.query_store_plan AS qp
        ON rs.plan_id = qp.plan_id
    JOIN sys.query_store_query AS q
        ON qp.query_id = q.query_id
    JOIN sys.query_store_query_text AS qt
        ON q.query_text_id = qt.query_text_id
    JOIN sys.query_store_runtime_stats_interval AS rs_interval
        ON rs.runtime_stats_interval_id = rs_interval.runtime_stats_interval_id
    WHERE rs_interval.start_time >= @from1
      AND rs_interval.start_time < @to2
      AND (
            rs_interval.start_time < @to1
         OR rs_interval.start_time >= @from2
          )
      AND qt.query_sql_text NOT LIKE '%sys.%'  -- システムクエリの除外例
)
, agg AS (
    SELECT
        period,
        query_sql_text,
        executions = SUM(count_executions),
        total_cpu_ms = SUM(avg_cpu_time * count_executions) / 1000.0,
        total_duration_ms = SUM(avg_duration * count_executions) / 1000.0,
        total_logical_reads = SUM(avg_logical_io_reads * count_executions),
        total_physical_reads = SUM(avg_physical_io_reads * count_executions)
    FROM qs
    WHERE period IS NOT NULL
    GROUP BY period, query_sql_text
)
SELECT
    COALESCE(a.query_sql_text, b.query_sql_text) AS query_text,
    a.executions AS exec_2023_04,
    b.executions AS exec_2024_04,
    b.executions - a.executions AS exec_diff,
    a.total_cpu_ms AS cpu_ms_2023_04,
    b.total_cpu_ms AS cpu_ms_2024_04,
    b.total_cpu_ms - a.total_cpu_ms AS cpu_diff_ms,
    a.total_physical_reads AS phy_read_2023_04,
    b.total_physical_reads AS phy_read_2024_04,
    b.total_physical_reads - a.total_physical_reads AS phy_read_diff
FROM agg AS a
FULL OUTER JOIN agg AS b
    ON a.query_sql_text = b.query_sql_text
   AND a.period = '2023-04'
   AND b.period = '2024-04'
WHERE COALESCE(a.query_sql_text, b.query_sql_text) IS NOT NULL
ORDER BY cpu_diff_ms DESC;

このように Query Store を使うと、次のような分析が簡単になります。

  • 前年同月と比べて CPU 消費が急増したクエリ を抽出
  • 実行回数は大きく増えたが物理読み取りの増加は小さいクエリ(キャッシュヒット率が改善している可能性)
  • 物理読み取りだけが増えているクエリ(インデックス設計や統計情報に課題)

Query Store 統計を中央DBに集約して分析する

複数のアプリケーション DB がある場合、各 DB に対して同様のクエリを実行し、結果を中央のレポート用 DB に集約すると分析が楽になります。

SELECT *
INTO CentralDB.dbo.QueryStore_Stats_2024_04
FROM (
    -- 上記の Query Store 集計クエリを
    -- 必要な列だけに絞ってサブクエリ化し、
    -- DB 名なども付与して INSERT/SELECT するイメージ
) AS x;

あとは Power BI・Excel Power Pivot・任意の BI ツール で前年同月比のグラフを作成すれば、「どの DB・どのクエリがどれだけ重くなったか」を一目で確認できます。

DMVスナップショットでファイル単位のI/O負荷を比較する

Query Store はクエリ単位の分析に強い一方、データベース・ファイル単位で I/O 負荷を見たいときには sys.dm_io_virtual_file_stats が有効です。ただし DMV は累積カウンタなので、そのままでは「2023年4月の I/O 量」だけを取り出すことはできません。

そこで、定期的に DMV の値を履歴テーブルに保存し、期間の開始と終了時点の差分を取るパターンを使います。

I/O履歴テーブルの例

CREATE TABLE dbo.IoStatsHistory (
    capture_time          DATETIME2(0) NOT NULL,
    database_id           INT          NOT NULL,
    file_id               INT          NOT NULL,
    num_of_reads          BIGINT       NOT NULL,
    num_of_bytes_read     BIGINT       NOT NULL,
    io_stall_read_ms      BIGINT       NOT NULL,
    num_of_writes         BIGINT       NOT NULL,
    num_of_bytes_written  BIGINT       NOT NULL,
    io_stall_write_ms     BIGINT       NOT NULL,
    io_stall              BIGINT       NOT NULL,
    size_on_disk_mb       BIGINT       NOT NULL,
    CONSTRAINT PK_IoStatsHistory PRIMARY KEY (capture_time, database_id, file_id)
);

SQL Agentジョブで定期スナップショットを取得

次のような INSERT 文を SQL Agent ジョブとして、たとえば 5〜15 分間隔で実行します。

INSERT INTO dbo.IoStatsHistory (
    capture_time,
    database_id,
    file_id,
    num_of_reads,
    num_of_bytes_read,
    io_stall_read_ms,
    num_of_writes,
    num_of_bytes_written,
    io_stall_write_ms,
    io_stall,
    size_on_disk_mb
)
SELECT
    SYSDATETIME(),
    vfs.database_id,
    vfs.file_id,
    vfs.num_of_reads,
    vfs.num_of_bytes_read,
    vfs.io_stall_read_ms,
    vfs.num_of_writes,
    vfs.num_of_bytes_written,
    vfs.io_stall_write_ms,
    vfs.io_stall,
    (vfs.size_on_disk_bytes / 1024 / 1024)
FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vfs;

これにより、各 DB ファイルの読み取り/書き込み回数・バイト数・I/O 待ち時間が時系列で蓄積されます。

特定期間のファイル単位I/O負荷を算出し、前年同月と比較する

次に、2023年4月と2024年4月の月間 I/O 負荷をファイル単位で集計し、前年同月比を見てみます。

DECLARE @from1 DATETIME2 = '2023-04-01 00:00:00';
DECLARE @to1   DATETIME2 = '2023-05-01 00:00:00';
DECLARE @from2 DATETIME2 = '2024-04-01 00:00:00';
DECLARE @to2   DATETIME2 = '2024-05-01 00:00:00';

;WITH snap AS (
    SELECT
        period = CASE
                    WHEN capture_time >= @from1 AND capture_time < @to1 THEN '2023-04'
                    WHEN capture_time >= @from2 AND capture_time < @to2 THEN '2024-04'
                 END,
        capture_time,
        database_id,
        file_id,
        num_of_reads,
        num_of_bytes_read,
        num_of_writes,
        num_of_bytes_written,
        io_stall_read_ms,
        io_stall_write_ms
    FROM dbo.IoStatsHistory
    WHERE capture_time >= @from1
      AND capture_time < @to2
)
, first_last AS (
    SELECT
        period,
        database_id,
        file_id,
        MIN(capture_time) AS first_time,
        MAX(capture_time) AS last_time
    FROM snap
    WHERE period IS NOT NULL
    GROUP BY period, database_id, file_id
)
, diff AS (
    SELECT
        f.period,
        f.database_id,
        f.file_id,
        s_last.num_of_reads         - s_first.num_of_reads         AS reads,
        s_last.num_of_bytes_read    - s_first.num_of_bytes_read    AS read_bytes,
        s_last.num_of_writes        - s_first.num_of_writes        AS writes,
        s_last.num_of_bytes_written - s_first.num_of_bytes_written AS write_bytes,
        s_last.io_stall_read_ms     - s_first.io_stall_read_ms     AS io_stall_read_ms,
        s_last.io_stall_write_ms    - s_first.io_stall_write_ms    AS io_stall_write_ms
    FROM first_last AS f
    JOIN snap AS s_first
        ON f.period = s_first.period
       AND f.database_id = s_first.database_id
       AND f.file_id = s_first.file_id
       AND f.first_time = s_first.capture_time
    JOIN snap AS s_last
        ON f.period = s_last.period
       AND f.database_id = s_last.database_id
       AND f.file_id = s_last.file_id
       AND f.last_time = s_last.capture_time
)
SELECT
    DB_NAME(d.database_id) AS db_name,
    d.file_id,
    d2023.reads       AS reads_2023_04,
    d2024.reads       AS reads_2024_04,
    d2024.reads - d2023.reads AS reads_diff,
    d2023.read_bytes  AS read_bytes_2023_04,
    d2024.read_bytes  AS read_bytes_2024_04,
    d2024.read_bytes - d2023.read_bytes AS read_bytes_diff,
    d2023.io_stall_read_ms  AS stall_read_2023_04,
    d2024.io_stall_read_ms  AS stall_read_2024_04,
    d2024.io_stall_read_ms - d2023.io_stall_read_ms AS stall_read_diff
FROM (
    SELECT DISTINCT database_id, file_id FROM diff
) AS d
LEFT JOIN diff AS d2023
    ON d.database_id = d2023.database_id
   AND d.file_id = d2023.file_id
   AND d2023.period = '2023-04'
LEFT JOIN diff AS d2024
    ON d.database_id = d2024.database_id
   AND d.file_id = d2024.file_id
   AND d2024.period = '2024-04'
ORDER BY read_bytes_diff DESC;

この結果から、次のようなことが分かります。

  • 特定の DB のログファイルだけ I/O 増加が大きい → トランザクション量やログバックアップの間隔見直しが必要かもしれない
  • 一部のデータファイルだけ物理読み取りと I/O 待ち時間が共に増加 → テーブル配置やインデックス設計、ストレージ性能を要確認
  • 読み取り量は増えたが I/O 待ち時間は減っている → ストレージ性能増強やキャッシュヒット率向上の効果が出ている

待機統計と組み合わせて「本当にI/Oがボトルネックか」を確認する

I/O 量だけ増えていても、必ずしも性能問題とは限りません。そこで sys.dm_os_wait_stats などの待機統計を「前年同月比」で見ることで、本当にユーザー影響が出ているかを判断しやすくなります。

DMV の待機統計も累積値なので、I/O と同じく履歴テーブルにスナップショットを保存し、差分を計算するパターンを取ります。

CREATE TABLE dbo.WaitStatsHistory (
    capture_time DATETIME2(0) NOT NULL,
    wait_type    NVARCHAR(120) NOT NULL,
    waiting_tasks_count BIGINT NOT NULL,
    wait_time_ms BIGINT NOT NULL,
    signal_wait_time_ms BIGINT NOT NULL,
    CONSTRAINT PK_WaitStatsHistory PRIMARY KEY (capture_time, wait_type)
);

INSERT INTO dbo.WaitStatsHistory
SELECT
    SYSDATETIME(),
    wait_type,
    waiting_tasks_count,
    wait_time_ms,
    signal_wait_time_ms
FROM sys.dm_os_wait_stats;

あとは IoStatsHistory と同様に期間の差分を取り、PAGEIOLATCH_* や WRITELOG の待機時間が前年同月と比べてどれだけ増減したかを調べます。I/O 量は増えているのに I/O 関連の待機時間はむしろ減っているのであれば、ストレージやキャッシュ周りは改善されている可能性が高く、「遅さ」の原因は別の待機(ロック、並列処理、ネットワークなど)にあると考えられます。

Extended Eventsで問題クエリをピンポイントに追いかける

Query Store や DMV だけでは、特定の時間帯やクエリに絞った詳細なトレースがしづらい場面もあります。そうした場合は、Extended Events で I/O の重いクエリだけを短期間キャプチャする方法が有効です。

例:物理読み取りの多いステートメントをファイルに記録する

CREATE EVENT SESSION [Xe_IoHeavyStatements]
ON SERVER
ADD EVENT sqlserver.sql_statement_completed (
    ACTION (
        sqlserver.sql_text,
        sqlserver.database_id,
        sqlserver.session_id
    )
    WHERE (
        physical_reads >= 10000    -- しきい値は環境に合わせて調整
        OR logical_reads >= 100000
    )
)
ADD TARGET package0.asynchronous_file_target (
    SET filename = N'C:\XE\IoHeavyStatements.xel',
        max_file_size = 100,
        max_rollover_files = 5
)
WITH (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS);
GO

ALTER EVENT SESSION [Xe_IoHeavyStatements] ON SERVER STATE = START;

負荷の高い期間(たとえば月末バッチの時間帯)だけセッションを有効化し、その後 SSMS などで .xel ファイルを読み込めば、「どのステートメントが I/O をどれだけ発生させていたか」を詳しく確認できます。前年同月のトレースファイルが残っていれば、同じ観点で比較することも可能です。

Extended Events は非常に強力ですが、イベント数が多くなるとディスク使用量が増大し、場合によっては性能への影響も出ます。期間を限定し、対象イベントとしきい値を慎重に絞ることが大事です。

PerfMonとOSレベル監視で長期トレンドをつかむ

SQL Server 内部の情報だけでなく、OS 側のカウンタも前年同月比較に役立ちます。Windows の Performance Monitor(PerfMon)では、以下のようなカウンタを長期収集するとよいでしょう。

  • \SQLServer:SQL Statistics\Batch Requests/sec
  • \SQLServer:Buffer Manager\Page life expectancy
  • \LogicalDisk\Disk Reads/sec, Disk Writes/sec
  • \LogicalDisk\Avg. Disk sec/Read, Avg. Disk sec/Write
  • \Processor(_Total)\% Processor Time

PerfMon のデータコレクタセットを使って、1 分ごとにログを CSV 出力しておけば、Excel や Power BI に読み込んで「2023年4月」と「2024年4月」を重ねてグラフ表示できます。

  • ピーク時の Batch Requests/sec が同じなのに Disk sec/Read が悪化している → ストレージ側がボトルネック化している可能性
  • Batch Requests/sec 自体が倍近く増えている → 単純に処理量が増えているため、アプリ側の見直しやスケールアウトを検討

PerfMon の強みは、SQL Server に限らず OS 全体を一括で見られる点です。仮想化環境やクラウド環境では、ホストレベルのメトリクスと組み合わせることで、より正確なボトルネック分析が可能になります。

SQL Server標準GUI・レポート機能の位置づけ

SSMS には Activity Monitor や、レポートメニューから利用できる標準レポートが用意されています。これらは「今遅い」「今異常」といったリアルタイム診断に非常に便利ですが、長期比較には向きません。

  • Activity Monitor:セッション・待機・I/O ボトルネックのリアルタイム確認に最適。ただし履歴を残さない。
  • 標準レポート(ディスク使用量・トップクエリなど):一時的な状況確認に役立つが、前年同月比較をするには出力結果を保存・集計する必要がある。

これらは、問題発生中の「現場確認ツール」として割り切り、前年同月の比較やトレンド分析には Query Store・DMV・PerfMon などの履歴ベースの仕組みを使うのがおすすめです。

Data Collectorとサードパーティ監視ツールの使い分け

Data Collector(Management Data Warehouse)の特徴

Data Collector は SQL Server に標準搭載されている長期監視機能で、専用の Management Data Warehouse(MDW)に対してメトリクスを蓄積します。追加ライセンスなしでサーバ全体の統計を集約できるのは大きなメリットです。

一方で、GUI やレポートテンプレートが古く、最近のツールに比べると操作性や可視化の柔軟性は劣ります。既に MDW を使っている環境なら、そのまま前年同月比較用のビューやレポートを追加するのがコストパフォーマンスの良いアプローチです。

サードパーティ監視ツールの比較ポイント

継続的なモニタリングや、複数サーバの一括管理が必要な場合は、サードパーティ製ツールの導入を検討する価値があります。代表的な製品には次のようなものがあります。

  • SolarWinds Database Performance Analyzer (DPA) / Database Performance Monitor (DPM)
  • Redgate SQL Monitor
  • Quest Foglight / Spotlight
  • SentryOne
  • dbForge Monitor(SSMS 拡張)

これらのツールは、値段や得意分野が大きく異なりますが、共通する強みとして次が挙げられます。

  • 導入後すぐに履歴が自動で溜まり、カレンダーから日付を選ぶだけで前年同月比較レポートを出せる
  • グラフやダッシュボードが整備されており、SQL Server 以外の DB(Oracle、MySQL など)と一元管理できる製品も多い
  • エージェントレス接続に対応した製品が多く、クラウド環境でも導入しやすい
タイプメリットデメリット向いているケース
自前スクリプト+BIツール(Query Store / DMV)ライセンス費用がほぼ不要。必要な指標だけを柔軟に収集できる。設計・実装・メンテナンスに工数がかかる。担当者が変わると属人化しやすい。少数サーバ、技術者がいる中小規模の環境。コストを抑えたいケース。
Data Collector / MDWSQL Server 標準機能だけで完結。追加コンポーネントが不要。UI が古く、柔軟な可視化には別途 BI ツールが必要。既に MDW を運用している組織。SQL Server 中心の環境。
サードパーティ監視ツールセットアップ直後から使えるダッシュボードとアラート。日/週/月の比較レポートが用意されている。ライセンス費用が発生する。ツールの運用・アップグレードも管理が必要。サーバ台数が多い、DBA チームが存在する中〜大規模環境。オンプレ+クラウド混在環境。

運用デザイン:差分取得と基準データベースの活用

前年同月比較を「毎年の恒例行事」にするには、以下のポイントを押さえて運用を設計しておくと効率的です。

差分取得を前提にスキーマとジョブを設計する

  • DMV(sys.dm_io_virtual_file_stats, sys.dm_os_wait_stats など)は累積カウンタであることを前提に設計する
  • 「いつリセットされるか」(SQL Server 再起動、カウンタの手動リセット)も合わせて記録しておく
  • 履歴テーブルには必ず capture_time を含める(主キーに含めておくと扱いやすい)

最初から「2024年4月の差分だけ取る」のではなく、基本は時系列ログとして取り続ける設計にしておくと、あとから「四半期単位で比較したい」「特定の障害発生日だけ見たい」といったニーズにも対応しやすくなります。

CentralDB(基準データベース)に集約する

運用上は、各 DB や各サーバに散在する統計情報を、監視用の中央 DB(例:CentralDB)に集約するのが現実的です。

  • 各サーバの SQL Agent で収集 → Linked Server や ETL ツールで CentralDB に転送
  • Query Store の集計結果を毎月末に CentralDB へ INSERT/SELECT して確定値として保存
  • Power BI やレポートサーバーからは CentralDB のみ参照するように統一

こうすることで、「2023年4月の状態」がローテーションやクリーンアップ設定に影響されない「確定値」として残り続け、翌年以降の比較が格段にやりやすくなります。

オンプレ+クラウド混在環境でのポイント

近年は、オンプレミスの SQL Server に加え、Azure SQL Managed Instance や Amazon RDS for SQL Server など、クラウドのマネージドサービスが混在するケースも増えています。このような環境で前年同月比較を行う場合は、次のポイントを意識しましょう。

  • クラウド側はインフラメトリクスの取得方法が異なる(クラウドポータルやモニタリングサービス経由)
  • Query Store や DMVs は基本的に同様に使えるため、DB レイヤーのスクリプトは流用しやすい
  • サードパーティ製ツールの中には、クラウドマネージド DB を正式サポートしているものとそうでないものがある

オンプレ・クラウドをまたいで前年同月比較を行う場合、クラウド対応を明言しているツール(DPA や SQL Monitor など)を採用しておくと、異なる環境間でも同じダッシュボードで比較できるため運用がシンプルになります。

まとめ:何から始めるか

SQL Server で「異なる年の同一月」を比較し、I/O 負荷とパフォーマンスを把握するには、次のステップで考えるとスムーズです。

  1. どの指標をどの粒度で比較したいか決める
    (クエリ単位・ファイル単位・サーバ全体、月トータル・ピーク日など)
  2. Query Store と DMV スナップショットを軸に、差分取得の仕組みを自動化する
  3. CentralDB に統合し、前年同月の確定値を残す
  4. PerfMon(またはサードパーティツール)で OS/インフラレベルのトレンドも合わせて見る
  5. 必要に応じて Extended Events で問題クエリをピンポイント調査する

短期間での検証や少数サーバであれば、まずは Query Store と DMV を組み合わせた自前スクリプト+Excel/Power BI から始めるのがおすすめです。サーバ台数が増え、オンプレとクラウドが混在するようであれば、長期的にはサードパーティ製の監視ツールを導入し、「前年同月比較」や「トレンド分析」を日常的な運用に組み込んでいくと、性能問題の早期発見とキャパシティプランニングが格段に楽になります。

いずれの方法を選ぶにしても、「いつ」「どの指標」を取り、「差分をどう保管するか」を最初に決めておくことが、翌年以降の比較をスムーズにする最大のポイントです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次