次の方法で共有


クエリ ストアのヒント、ベスト プラクティス

適用対象: Sql Server 2022 (16.x) 以降のバージョン Azure SQL DatabaseAzure SQL Managed InstanceSQL データベース (Microsoft Fabric プレビュー)

この記事では、クエリ ストア ヒント を使用する場合のベスト プラクティスについて詳しく説明します。 クエリ ストア ヒントを使用すると、アプリケーション コードを変更することなくクエリ プランを形成できます。

クエリ ストア ヒントのユース ケース

次のユース ケースをクエリ ストア ヒントの理想と考えてください。 詳細については、「いつクエリ ストア ヒントを使用するか」を参照してください。

Caution

通常、クエリにとって最適な実行プランが SQL Server クエリ オプティマイザーによって選択されるため、ヒントは、経験を積んだ開発者やデータベース管理者が最後の手段としてのみ使用することをお勧めします。 詳細については、クエリ ヒントを参照してください。

コードを変更できない場合

クエリ ストア ヒントを使用すると、アプリケーション コードやデータベース オブジェクトを変更することなく、クエリの実行プランに影響を与えることができます。 クエリ ヒントをすばやく簡単に適用できる他の機能はありません。

たとえば、クエリ ストア ヒントを使用すると、コードを再デプロイすることなく、抽出-変換-読み込み (ETL) ワークロードにメリットをもたらします。 この 14 分間のビデオでは、クエリ ストア ヒントを使用して一括読み込みを改善する方法について説明しています。

クエリ ストア ヒントは軽量なクエリ チューニング方法ですが、クエリに問題が発生した場合は、より大幅なコード変更による対処が必要になります。 クエリ ストア ヒントをクエリに適用する必要がある場合は、クエリの書き換えを大きくすることを検討してください。 SQL Server クエリ オプティマイザーは、通常、クエリに最適な実行プランを選択します。 経験豊富な開発者とデータベース管理者の最後の手段としてヒントのみを使用することをお勧めします。

どのクエリ ヒントを適用できるかについては、「サポートされているクエリ ヒント」を参照してください。

トランザクション負荷が高い場合、またはミッション クリティカルなコードを使用する場合

アップタイム要件やトランザクション負荷が高いためにコードの変更が実用的でない場合、クエリ ストア ヒントを使用すると、既存のクエリ ワークロードにクエリ ヒントをすばやく適用できます。 クエリ ストア ヒントの追加と削除は簡単です。

クエリ ストア ヒントは、クエリのバッチに対して追加と削除を行い、例外的なワークロードのバーストに対する時間枠のパフォーマンスを調整できます。

プランガイドの代替として

クエリ ストア ヒント以前には、開発者は同様のタスクを実行するためにプラン ガイドに依存しなければなりませんでしたが、それは複雑で使いづらいことがありました。 クエリ ストア ヒントは、クエリを視覚的に探索するために、SQL Server Management Studio (SSMS) のクエリ ストア機能と統合されています。

プラン ガイドでは、クエリ スニペットを使用してすべてのプランを検索する必要があります。 クエリ ストア ヒント機能では、結果のクエリ プランに影響を与えるために完全に一致するクエリは必要ありません。 クエリ ストア ヒントは、クエリ ストア データセット内の query_id に適用できます。

クエリ ストア ヒントは、ハードコーディングされたステートメント レベルのヒントと既存のプラン ガイドをオーバーライドします。

新しい互換性レベルを検討する

たとえば、ベンダーの仕様やテストの遅延が大きいため、新しいデータベース互換性レベルが使用できない場合、クエリ ストア ヒントは重要な方法になります。 より高い互換性レベルをデータベースで使用できる場合は、個人のクエリのデータベースの互換性レベルをアップグレードして、SQL Server の最新のパフォーマンス最適化と機能を活用することを検討してください。

たとえば、互換性レベル 140 のデータベースを持つ SQL Server 2022 (16.x) インスタンスがある場合でも、クエリ ストア ヒントを使用して、互換性レベル 160 で個々のクエリを実行できます。 次のヒントを使用できます。

EXEC sys.sp_query_store_set_hints @query_id= 39, @query_hints = N'OPTION(USE HINT(''QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_160''))';

完全なチュートリアルについては、「クエリ ストアヒントの例」を参照してください。

アップグレード後に古い互換性レベルを検討する

クエリ ストア ヒントが役立つもう 1 つのケースは、SQL Server インスタンスの移行またはアップグレードの直後にクエリを変更できない場合です。 クエリ ストア ヒントを使用して、クエリが書き換えられるか、最新の互換性レベルで適切に実行されるように対処できるようになるまで、クエリに以前の互換性レベルを適用します。 クエリ ストアの後退したクエリ レポート、移行中のクエリ チューニング アシスタント ツール、またはその他のクエリ レベルのアプリケーション テレメトリを使用して、より高い互換性レベルで後退した外れ値クエリを特定します。 互換性レベルの違いの詳細については、「互換性レベルの違い」を参照してください。

この方法で新しい互換性レベルをテストし、クエリ ストア ヒントをデプロイした後、コードを変更することなく、以前の互換性レベルで主要な問題のあるクエリを維持しながら、データベース全体の互換性レベルをアップグレードできます。

問題のあるクエリの将来の実行をブロックする

ABORT_QUERY_EXECUTION クエリ ヒントを使用して、既知の問題のあるクエリの将来の実行をブロックできます。たとえば、不要なクエリによってリソースの消費量が多くなり、重要なアプリケーション ワークロードに影響を与えます。

Note

現時点では、 ABORT_QUERY_EXECUTION (プレビュー) クエリ ヒントは、Azure SQL Database と SQL Server 2025 (17.x) プレビューでのみ使用できます。

たとえば、 query_id 39 の今後の実行をブロックするには、次のように sys.sp_query_store_set_hints 実行します。

EXEC sys.sp_query_store_set_hints
     @query_id = 39,
     @query_hints = N'OPTION (USE HINT (''ABORT_QUERY_EXECUTION''))';

詳細については、「クエリ ストアのヒント の例」を参照してください。

次の考慮事項が適用されます。

  • クエリに対してこのヒントを指定すると、クエリの実行試行がエラー 8778、重大度 16 で失敗し、 ABORT_QUERY_EXECUTION ヒントが指定されたため、クエリの実行が中止されました。

  • クエリのブロックを解除するには、sys.sp_query_store_clear_hints ストアド プロシージャの query_id パラメーターに@query_id値を渡すことでヒントクリアできます。

  • 次のクエリ例のように、システム ビューを使用して、ブロックされているクエリ ストア内のクエリを検索できます。

    SELECT qsh.query_id,
           q.query_hash,
           qt.query_sql_text
    FROM sys.query_store_query_hints AS qsh
    INNER JOIN sys.query_store_query AS q
    ON qsh.query_id = q.query_id
    INNER JOIN sys.query_store_query_text AS qt
    ON q.query_text_id = qt.query_text_id
    WHERE UPPER(qsh.query_hint_text) LIKE '%ABORT[_]QUERY[_]EXECUTION%'
    
  • query_id値を取得するには、クエリ ストアに少なくとも 1 つのクエリ実行を記録する必要があります。 この実行は成功する必要はありません。 つまり、タイムアウトまたは取り消されたクエリの今後の実行がブロックされる可能性があります。

  • 特定のクエリ ハッシュを使用してすべてのクエリをブロックまたはブロック解除する必要がある場合は、自動化スクリプトの使用を検討してください。 たとえば、dbo.sp_query_store_modify_hints_by_query_hashは、クエリ ハッシュに一致するすべてのsys.sp_query_store_set_hints値に対して、sys.sp_query_store_clear_hintsまたはquery_idシステム ストアド プロシージャをループで呼び出すサンプル ストアド プロシージャです。

  • ブロック時にクエリが既に実行されている場合、その実行は続行されます。 KILL ステートメントを使用して、クエリを中止できます。

    • 強制終了されたクエリの実行はクエリ ストアに記録されません。 クエリがクエリ ストアにまだ存在しない場合は、クエリを完了またはタイムアウトさせて、ブロックできる query_id を取得する必要があります。
  • クエリがABORT_QUERY_EXECUTION ヒントによってブロックされると、sys.query_store_runtime_stats ビューのexecution_type列とexecution_type_desc列はそれぞれ 4 と例外に設定されます。

  • すべてのクエリ ストア ヒントと同様に、ALTER ヒントを設定およびクリアするには、データベースに対するABORT_QUERY_EXECUTION権限が必要です。

クエリ ストア ヒントに関する考慮事項

クエリ ストア ヒントを配置するときは、次のシナリオを検討してください。

データ分散の変更

プラン ガイド、クエリ ストアを使用した強制プラン、クエリ ストア ヒントは、オプティマイザーの決定をオーバーライドします。 クエリ ストア ヒントは、今後は役に立つかもしれませんが、今後は役に立たない可能性があります。 たとえば、クエリ ストア ヒントが以前のデータ分散のクエリに役立つ場合、大規模な DML 操作によってデータが変更されると、逆効果になる可能性があります。 新しいデータ分散により、オプティマイザーはヒントよりも適切な判断を下す可能性があります。 このシナリオは、プランの動作を強制することの最も一般的な結果です。

クエリ ストア ヒント戦略を定期的に再評価する

次の場合に、既存のクエリ ストア ヒント戦略を再評価します。

  • 既知の大規模なデータ分散が変更された後。
  • データベースで使用可能なリソースが変更されたとき。 たとえば、Azure SQL Database、SQL Managed Instance、または SQL Server 仮想マシンのコンピューティング サイズが変更された場合です。
  • プランの修正が長期間に渡って行われている場合。 クエリ ストア ヒントは、短期的な修正に最適です。
  • 予期しないパフォーマンスの低下。

広範な影響の可能性

クエリ ストア ヒントは、パラメーター セット、ソース アプリケーション、ユーザー、または結果セットに関係なく、クエリのすべての実行に影響します。 意図せずパフォーマンスが低下した場合、sys.sp_query_store_set_hints で作成されたクエリ ストア ヒントは、sys.sp_query_store_clear_hints で簡単に削除できます。

運用環境でクエリ ストア ヒントを適用する前に、ミッション クリティカルなシステムまたは機密性の高いシステムで変更の負荷テストを注意深く行います。

強制パラメーター化と RECOMPILE ヒントはサポートされていません

データベース オプション RECOMPILEされている場合、クエリ ストア ヒントを使用したクエリ ヒントの適用はサポートされません。 詳細については、「強制パラメーター化使用のガイドライン」をご覧ください。

RECOMPILE ヒントは、データベース レベルで設定された強制パラメーター化と互換性がありません。 データベースが強制パラメーター化を使用し、 RECOMPILE ヒントがクエリのクエリ ストアに設定されているヒント文字列の一部である場合、データベース エンジンは RECOMPILE ヒントを無視し、指定されている場合は他のヒントを適用します。 さらに、Azure SQL Database の 2022 年 7 月以降、 RECOMPILE ヒントが無視されたことを示す警告 (エラー コード 12461) が発行されます。

どのクエリ ヒントを適用できるかについては、「サポートされているクエリ ヒント」を参照してください。