クエリ ヒントは、既定では適切なクエリ プランが生成されない場合に、クエリ オプティマイザーをガイドするために使用されます。最初に、クエリ オプティマイザーの背景について簡単に説明します。
データベース プログラミングは、機械的なコンポーネントを備えているため、他のほとんどすべてのソフトウェア開発とは異なります。ディスクのシークと回転の待ち時間 (特定のセクターがディスク ヘッドの下に到着するのを待つ) は、CPU に比べて非常にコストがかかります。クエリ解決戦略が異なれば、I/O の量も異なり、多くの場合、根本的に異なる量になります。これが正しいか間違っているかによって、クエリのパフォーマンスに大きな違いが生じる可能性があります。クエリの最適化の概要については、このペーパーを参照してください。
SQL は宣言的です。クエリのロジックを指定し、DBMS に解決方法を理解させます。最新のコストベースのクエリ オプティマイザー (Oracle などの一部のシステムでは、下位互換性のために従来のクエリ オプティマイザーも保持されています) は、クエリに対して一連の変換を実行します。これらはセマンティックな同等性を維持しますが、操作の順序と選択が異なります。テーブルで収集された統計 (サイズ、キーの分散ヒストグラム) に基づいて、オプティマイザーは各クエリ プランに必要な作業量の見積もりを計算します。最も効率的なプランを選択します。
コストベースの最適化はヒューリスティックであり、正確な統計に依存しています。クエリの複雑さが増すと、ヒューリスティックが誤った計画を生成する可能性があり、非常に非効率になる可能性があります。
この状況でクエリ ヒントを使用して、結合の種類など、クエリ プランで特定の戦略を強制することができます。たとえば、通常非常に小さな結果セットを返すクエリでは、ネストされたループ結合を強制したい場合があります。テーブルの特定の結合順序を強制することもできます。
O/R マッパー (または SQL を生成するツール) は独自のクエリを生成しますが、これには通常、ヒント情報はありません。このクエリが非効率的に実行される場合、選択肢は限られています。その一部を次に示します。
テーブルのインデックスを調べます。おそらく、インデックスを追加できます。一部のシステム (最近のバージョンの Oracle など) では、複数のテーブルにまたがる結合にインデックスを付けることができます。
一部のデータベース管理システム (やはり Oracle が思い浮かびます) では、クエリ プランを特定のクエリ文字列に手動で関連付けることができます。クエリ プランは、クエリのハッシュ値によってキャッシュされます。クエリがパラメーター化されている場合、基本クエリ文字列は定数であり、同じハッシュ値に解決されます。
最後の手段として、データベース スキーマを変更できますが、これはアプリケーションを制御している場合にのみ可能です。
SQL を制御する場合は、クエリをヒントすることができます。実際には、実際にこれを行う必要があることはほとんどありません。複雑なデータベース スキーマを持つ O/R マッパーのより一般的な障害モードは、複雑なクエリ述語を表現したり、大量のデータに対して複雑な操作を実行したりすることが困難になる可能性があることです。
私は、O/R マッパーが適している 98% の作業に O/R マッパーを使用し、適切なソリューションであるストアド プロシージャにドロップすることを推奨する傾向があります。本当にクエリをヒントする必要がある場合は、これが適切な戦略かもしれません。アプリケーションに通常とは異なる点 (たとえば、ある種の DSS) がない限り、O/R マッパーからエスケープする必要があるのは少数の状況だけです。また、O/R マッパーが実際にはアプリケーションにとって適切な戦略ではないことに気付くかもしれません (ここでも、データを集約して操作する DSS ツールがその例です)。