!!!ヒント句とは {{category Oracle,nolink}}通常、テーブルやインデックスに関する統計情報を基にコストを求め、もっともコスト(読み込むデータブロック数)が少なくないアクセスパスで実行するようになっている。 その際に、統計情報に誤り(サンプリング数が少なかったり、アナライズ後大量にデータが変わったり、など)すると、オプティマイザが誤ったインデックスを使用したりする場合がある。 そういった場合に、オプティマイザに対してどのようなアクセスパスで実行するかを指示(ヒント)を与えることができる。オプティマイザは、これらのヒントを提案として使用し、文の実行計画を選択する。どのインデックスを使用するか等のヒントを与え、パフォーマンスの向上を行う。 但し、ヒントを与えたからと言って必ず使用されるわけではない。実際にどのインデックスがどのように使用されているかは、Oracle の「EXPLAIN PLAN (実行計画)」を見て判断する必要がある。 ""'''注意:'''テーブル名やインデックス名を間違えても、ただのコメントとして扱われエラーにはならない。 ""'''参照:'''ヒントの詳細は、『Oracle9i データベース・パフォーマンス・チューニング・ガイドおよびリファレンス』および『Oracle9i データベース概要』を参照のこと。 !!!ヒント句の構文 ヒント句は、SQL文のSELECT,INSERT,UPDATE,DELETEのいずれかのキーワードの直後にコメントとして一つだけ記述する。 SELECT ┐ ┌←───────┐ UPDATE ┼─ /*+ ┴ Hint ┬───┬┴ */ →─ INSERT │ └ Text ┘ DELETE ┘ *'+ (プラス記号)'は、コメントをヒントのリストとして、Oracle に解析させる。プラス記号は、コメント・デリミタの直後に置く必要があり、空白を入れてはいけない。 *'Hint'は、下記のヒントの1つ。プラス記号とヒントの間の空白は入れても入れなくてもかまわない。コメントに複数のヒントが含まれている場合は、1 つ以上の空白で区切る必要がある。 *'Text'は、ヒントに含めることができるその他のコメント・テキストです。 *"{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]] ..."の形式でもOK !!インデックス使用時の注意 *TABLE_NAMEは必須、INDEX_NAMEは任意 *表名に別名(エイリアス)を使用してる場合、TABLE_NAMEは、別名の方を指定 *TABLE_NAMEの指定がない場合は、ヒントは無視 *INDEX_NAMEの指定がない場合は、すべての牽引が指定されたと同じ *TABLE_NAMEおよびINDEX_NAMEの指定が間違っている場合は、ヒントは無視 *INDEX_NAMEの指定が複数場合は、オプティマイザが統計に基づき、最もコストが低い索引を選択。もしくは、複数の索引にアクセスし、その結果をマージするようなアクセス・パスを選択。 !!!最適化目標と方法のヒント コストベースの最適化アプローチ(最高のスループットまたは最短応答時間)またはルールベースの最適化アプローチを指定する。 最適化アプローチと目標を指定するヒントがSQL文に含まれている場合、オプティマイザは、統計の有無、OPTIMIZER_MODE初期化パラメータの値およびALTER SESSION文のPTIMIZER_MODEパラメータにかかわらず、指定されたアプローチを使用する。 !!ALL_ROWS - 最高のスループットアプローチ 最高のスループットを目標として(合計のリソース使用率を最小限にして)文ブロックを最適化するために、コストベースのアプローチを選択します。 !!FIRST_ROWS(n) - 最短応答時間アプローチ 最初のn行(nは正の整数)までの応答が高速になるように個々のSQL文を最適化することを指示する。 FIRST_ROWSヒントは、最初の1行を戻す計画を最適化するためのものであり、下位互換性とプラン・スタビリティのために保持されている。 DELETE文ブロックとUPDATE文ブロック、および次の構文のいずれかが含まれているSELECT文ブロックでこのヒントを無視します。 *集合演算子(UNION、INTERSECT、MINUS、UNION ALL) *GROUP BY句 *FOR UPDATE句 *集計関数 *DISTINCT演算子 *順序付けする列に索引がない場合のORDER BY句 最初の行を戻す前に、文によってアクセスされた行をすべて取り出す必要があるため、これらの文は最短の応答時間を目標に最適化することができません。このような文にこのヒントを指定しても、オプティマイザはコストベースのアプローチを使用して、最高のスループットを目標に最適化を行う。 !!CHOOSE - コストベースとルールベースの選択 オプティマイザにルールベースのアプローチとコストベースのアプローチのどちらかを選択させる。 オプティマイザによる選択の基準は、文がアクセスする表に対する統計が存在すかである。1つ以上存在する場合は、コストベースのアプローチを使用し、最高のスループットを目標にして最適化します。 !!RULE - ルールベースの最適化アプローチ ルールベースのアプローチを行うように指定する。他のヒントは無視される。 ""'''注意:'''ルールベースの最適化は、将来のリリースでは、使用されなくなります。 !!!アクセス方法のヒント 表のアクセス・パスを指示するヒントです。これらのヒントを指定すると、指定されたアクセス・パスが索引やクラスタの存在およびSQL文の構文構造体に基づいて使用できる場合のみ、オプティマイザはそのアクセス・パスを選択する。ヒントを使用できないアクセス・パスを指定すると、オプティマイザはその指定を無視する。 アクセスする表は、文に指定する場合と同じように正確に指定する。文が表の別名を使用している場合、表の名前ではなく、表の別名をヒントで使用する必要がある。スキーマ名が文中にある場合は、ヒント内の表名にそのスキーマ名を入れない。 !!FULL - フル(全表)・スキャン 指定された表に対して全表スキャンを選択する。 /*+ FULL( table ) */ ''table'' は、全表スキャンが行われる表の名前または別名です。 !!ROWID - ROWIDによる表スキャン 指定された表に対してROWIDによる表スキャンを選択する。 /*+ ROWID( table ) */ ''table'' は、ROWID によってアクセスされる表の名前または別名です。 !!CLUSTER - クラスタ・スキャン 指定された表をアクセスするためにクラスタ・スキャンを選択する。これはクラスタ化オブジェクトにのみ適用される。 /*+ CLUSTER ( table ) */ ''table'' は、クラスタ・スキャンによってアクセスされる表の名前または別名です。 !!HASH - ハッシュ・スキャン 指定された表をアクセスするためにハッシュ・スキャンを選択する。これは、クラスタに格納されている表にのみ適用される。 /*+ HASH ( table ) */ ''table'' は、ハッシュ・スキャンによってアクセスされる表の名前または別名です。 !!INDEX - インデックス・スキャン(索引走査) 指定された表をアクセスするためにインデックス・スキャンを選択する。 /*+ INDEX( table index [,index ...] ) */ ''table'' は、索引走査が行われる表の名前または別名です。 ''index'' は、索引走査に使用する索引の名前です。 !!INDEX_ASC - 索引昇順走査 /*+ INDEX_ASC( table index [,index ...] ) */ !!INDEX_DESC - 索引降順走査 /*+ INDEX_DESC( table index [,index ...] ) */ !!INDEX_FFS - ファースト・フルスキャン(高速全索引走査) 指定された表をアクセスするために高速全索引走査を選択する。 /*+ INDEX_FFS( table index [,index ...] ) */ ''table'' は、索引スキャンが行われる表の名前または別名です。 ''index'' は、索引スキャンに使用する索引の名前です。 ※ 初期化パラメータに「fast_full_scan_enabled=true」が必要。 !!INDEX_FFS_ASC - 高速全索引昇順走査 /*+ INDEX_ASC( table index [,index ...] ) */ !!INDEX_FFS_DESC - 高速全索引降順走査 /*+ INDEX_FFS_DESC( table index [,index ...] ) */ !!INDEX_COMBINE - !!AND_EQUAL !!NO_INDEX !!!結合順序のヒント !!ORDERED !!STAR !!!結合操作のヒント !!DRIVING_SITE !!HASH_SJ !!MERGE_SJ !!NL_SJ !!LEADING !!USE_HASH !!USE_MERGE !!USE_NL !!!パラレル実行のヒント !!PARALLEL !!NOPARALLEL !!PARALLEL_INDEX !!PQ_DISTRIBUTE !!NOPARALLEL_INDEX !!!問合せ変換のヒント !!EXPAND_GSET_TO_UNION !!NO_EXPAND !!FACT !!NOFACT !!MERGE !!NO_MERGE !!REWRITE !!NOREWRITE !!STAR_TRANSFORMATION !!USE_CONCAT !!!その他のヒント !!APPEND !!NOAPPEND !!CACHE !!NOCACHE !!CURSOR_SHARING_EXACT !!DYNAMIC_SAMPLING !!NESTED_TABLE_GET_REFS !!UNNEST !!NO_UNNEST !!ORDERED_PREDICATES !!PUSH_PRED !!NO_PUSH_PRED !!PUSH_SUBQ !!NO_PUSH_SUBQ !!!ルールベース・オプティマイザ !!アクセス・パス 以下のような条件でアクセスパスがランク付けされる。ルールベースでは、一番高いランクのアクセスパスを選択する。 +明示的にROWIDをWhere句に指定した場合。CURRENT OF句を指定してコンパイルされてる場合。 +クラスタ結合により、単一行を戻す場合。 +主キーまたはユニークキーが指定されたハッシュ・クラスタにより単一行が戻される場合。 +主キーまたはユニークキー列を全てを、Where句でイコール比較した場合。 +クラスタキー全てがWhere句でイコール比較された場合。 +ハッシュ・クラスタキー全てがWhere句でイコール比較された場合。 +索引クラスタキー全てをWhere句でイコール比較した場合。 +複合索引全てをWhere句でイコール比較した場合。 +単一索引をWhere句でイコール比較した場合。複数の単一索引をAND接続しイコール比較した場合。 +単一索引、複合索引の先頭列をWhere句で有界(下限・上限がある)範囲検索した場合。 +単一索引、複合索引の先頭列をWhere句で非有界(下限・上限どちらかが無い)範囲検索した場合。 +ソート/マージ結合される場合。 +単一索引、複合索引の先頭列のみをMAX,MIN関数で選択した場合。 +単一索引または、複合索引の先頭列をORDER BY句に指定した場合。 +全表走査。上記に当てはまらない場合。