次の方法で共有


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

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

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

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

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

注意事項

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

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

たとえば、 query_id 39 の今後の実行をブロックするには、次のステートメントを実行します。

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 つのクエリ実行を記録する必要があります。 この実行は成功する必要はありません。 つまり、タイムアウトまたは取り消されたクエリの今後の実行がブロックされる可能性があります。
  • ブロック時にクエリが既に実行されている場合、その実行は続行されます。 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) が発行されます。

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