実行計画を“記録し、比べ、安定させる”Query Storeの力
SQL Server 2016以降に搭載されたQuery Storeは、クエリの実行履歴と実行計画を自動的に記録し、
性能劣化(Regression)を検知・分析・修正できる強力な機能です。
従来はDMVやキャッシュから瞬間的にしか見えなかった情報を、Query Storeは永続化し、
“過去と今を比較してチューニングする”ことを可能にします。
本記事では、Query Storeの基本構造・設定方法・代表的な活用例を実務視点で解説します。
目次
第1章 Query Storeとは何か
Query Storeは、SQL Server内部に「クエリ性能の時系列データベース」を作る仕組みです。
実行計画キャッシュと異なり、サーバー再起動後もデータが保持されます。
そのため、過去との比較・分析が可能になります。
- 実行されたクエリテキストとハッシュ
- 使用された実行計画(Plan ID単位)
- CPU時間・I/O・実行回数などの統計情報
- 計画変更による性能劣化(Plan Regression)の検出
簡単に言えば、Query Storeは「自動トレース+実行計画の履歴台帳」です。
第2章 Query Storeの有効化と構成
Query Storeはデータベース単位で有効化します。 既定では新規データベースではOFFの場合が多いので、明示的に設定します。
-- Query Store を有効化
ALTER DATABASE SalesDB
SET QUERY_STORE = ON;
-- 記録モードを有効化(読み取り専用時はOFFに注意)
ALTER DATABASE SalesDB
SET QUERY_STORE (OPERATION_MODE = READ_WRITE);
構成オプションでは、保持期間・サイズ上限・キャプチャポリシーを指定可能です。
ALTER DATABASE SalesDB
SET QUERY_STORE = ON
(
CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30),
DATA_FLUSH_INTERVAL_SECONDS = 900,
MAX_STORAGE_SIZE_MB = 2048,
INTERVAL_LENGTH_MINUTES = 60,
QUERY_CAPTURE_MODE = AUTO
);
QUERY_CAPTURE_MODEには以下の3モードがあります。
- AUTO:高負荷時は低頻度クエリをスキップ(推奨)
- ALL:すべて記録(検証・分析向け)
- NONE:一時停止(データ保持は継続)
第3章 内部構造と主要ビュー
Query Storeのデータはシステムビューを通して参照できます。 主な構成要素は以下の通りです。
| ビュー名 | 内容 |
|---|---|
| sys.query_store_query_text | 実行されたクエリのテキスト |
| sys.query_store_query | クエリごとの情報(作成日時・ハッシュなど) |
| sys.query_store_plan | 各クエリの実行計画情報 |
| sys.query_store_runtime_stats | 実行統計(CPU時間・I/O・回数) |
| sys.query_store_runtime_stats_interval | 時間帯ごとの統計区間 |
これらをJOINすることで「どのクエリが、どの時間帯に、どのプランで、どの程度の負荷を与えたか」を可視化できます。
-- 上位CPU消費クエリの抽出例
SELECT TOP 10
qt.query_sql_text,
rs.avg_cpu_time,
rs.count_executions,
p.plan_id
FROM sys.query_store_query_text AS qt
JOIN sys.query_store_query AS q ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan AS p ON q.query_id = p.query_id
JOIN sys.query_store_runtime_stats AS rs ON p.plan_id = rs.plan_id
ORDER BY rs.avg_cpu_time DESC;
第4章 実行計画の分析と比較
Query Storeの最大の強みは「過去の実行計画と現在の計画を比較できる」点です。 GUIでは SSMS → データベース → Query Store → 上位リソース消費クエリ からグラフ形式で確認できます。
また、T-SQLでも履歴比較が可能です。
-- 同一クエリでプランが変化したケースを検出
SELECT q.query_id, COUNT(DISTINCT p.plan_id) AS PlanCount
FROM sys.query_store_query AS q
JOIN sys.query_store_plan AS p ON q.query_id = p.query_id
GROUP BY q.query_id
HAVING COUNT(DISTINCT p.plan_id) > 1;
プランが複数存在する場合は、統計情報やパラメータ依存などが原因で最適化結果が変化している可能性があります。
第5章 プラン強制(Force Plan)の使い方
Query Storeの目玉機能がプラン強制(Force Plan)です。 性能劣化を引き起こした新しいプランを避け、過去の安定プランを再利用させることができます。
-- 特定クエリに安定プランを強制適用
EXEC sp_query_store_force_plan @query_id = 125, @plan_id = 3;
-- 解除
EXEC sp_query_store_unforce_plan @query_id = 125, @plan_id = 3;
SSMSからも「クエリストアレポート → 実行計画の比較」で右クリックから「強制プラン」を設定可能です。 ただし、プラン強制は万能ではなく、テーブルスキーマ変更やインデックス削除後は再コンパイルされます。
第6章 性能劣化の検知と対処
Query Storeには「自動回帰検出(Automatic Plan Correction)」という仕組みがあり、 性能が低下したプランを自動で過去の安定版に戻すことができます(SQL Server 2017以降)。
-- 機能の有効化
ALTER DATABASE SalesDB
SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = ON);
この設定により、プラン変更による急激な性能劣化を自動で補正可能です。 ログには「自動的に過去のプランへ戻した」旨が記録され、DBAの負担を軽減します。
第7章 運用時の注意点とベストプラクティス
- ストレージ容量: MAX_STORAGE_SIZE_MBを超えるとキャプチャが自動停止します。定期クリーンアップを設定。
- データ保持期間: CLEANUP_POLICYで古い履歴を自動削除(30〜90日が一般的)。
- 一時停止運用: 大規模メンテ時は READ_ONLY に切り替えてログ量を抑制。
- 統計情報の更新: Query Storeで検出したプラン変化の多くは統計の劣化が原因。IT0033記事へ接続。
- バックアップ対象: Query StoreはDB内オブジェクトのため、通常のDBバックアップで保護される。
-- Query Store の状態確認
SELECT actual_state_desc, current_storage_size_mb
FROM sys.database_query_store_options;
まとめ:Query Storeで“見える化チューニング”を実現
Query Storeは、SQL Serverのチューニング文化を変える仕組みです。
実行計画・履歴・統計情報を一元的に把握することで、
「どのクエリが」「いつから」「なぜ遅くなったか」を再現性をもって分析できます。
従来のキャッシュベース調査では不可能だった過去との比較・自動修正を可能にし、
運用チームと開発チームの連携を大幅に効率化します。
参考リンク(公式ドキュメント)
- Query Store によるパフォーマンス監視
- Query Store の使用シナリオ
- 自動チューニング(Automatic Plan Correction)
- ALTER DATABASE SET (Query Store オプション)

0 件のコメント:
コメントを投稿