1)ヒントとは
ヒントは、SQLに記述し、SQLが指定したアクセスパスや実行計画でデータの取得や結合を行うためのものです。
通常、SQLを実行したとき、ORACLEデータベースでは、オプティマイザが表や索引の統計情報を基に、最適な実行計画を作成します。
そのためSQLを実行する人は、実行計画やアクセスパスを意識する必要がありませんが、特定の問合せに対してオプティマイザの決定よりも他の実行計画が有効であることが 判っている場合、ヒントを使用してオプティマイザに特定の実行計画を使用するようにできます。
2)ヒントの使用法
{SELECT | DELETE | UPDATE} /*+ hint [text] */
hint:後述するヒントを記述します。複数指定する場合は空白で区切ります
text:ヒント以外のコメントがある場合、記述します
・ヒントは、SELECT文、DELETE、UPDATE文に含むことができます
・ヒントを含むコメントは、 SELECT、DELETE、UPDATEコマンドの直後に指定します
・ヒントの指定が間違っている場合、ヒントは無視されます
例)副問合せを含む文でのヒントの使用(SAMPLE表のSEQ列、SAMPLE_TEST表のCOL3に索引を作成済み)
主問合せのSAMPLE表はフルテーブルスキャンが行われるが、副問合せのSAMPLE_TEST表は索引スキャンが行われるSQL
>SELECT /*+ FULL(sample) */ col1, col2
2 FROM sample
3 WHERE seq IN (SELECT /*+ INDEX(sample_test col3_ind) */ seq
4 FROM sample_test WHERE col3 = 100);
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 HASH JOIN(SEMI)
2 1 TABLE ACCESS (FULL) OF ’SAMPLE’
3 1 TABLE ACCESS (BY INDEX ROWID) OF ’SAMPLE_TEST’
4 3 INDEX (RANGE SCAN) OF ’ COL3_IND’ (NON-UNIQUE)
3)ヒントの種類
ヒントで指定したアクセス・パスが使用可能な場合のみ有効になります。
FULL
FULL:指定された表に対して、フル・テーブル・スキャンを選択します
FULL (表名)
例)SAMPLE表のCOL3列の中で値「1」が占める割合が大きい場合、索引スキャンは好ましくない。その為、
FULLヒントを使用して索引スキャンではなくフル・テーブル・スキャンを選択するように指定
( SAMPLE表のCOL3列に索引を作成済み)
/* 索引スキャンを使用した問合せ */
SQL>SELECT seq, col1, col3 FROM sample
2 WHERE col3 = 1;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF ’SAMPLE’
2 1 INDEX (RANGE SCAN) OF ’ COL3_IND’ (NON-UNIQUE)
/* FULLヒントを使用した問合せ */
SQL>SELECT /*+ FULL(sample) */ seq, col1, col3 FROM sample
2 WHERE col3 = 1;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF ’SAMPLE’
INDEX
INDEX:指定された表に対して、索引スキャンを選択します
INDEX (表名 索引名 [ 索引名・・・ ] )
索引を1つだけ指定した場合、指定した索引を使用して索引スキャンを行います。索引を複数指定した場合、指定した各索引のコスト、及び索引をマージした場合のコストを見積り、もっとも コストが低いアクセス・パスを使用して索引スキャンを行います。索引を指定しなかった場合、使用可能な各索引のコスト、及び索引をマージした場合のコストを見積り、 もっともコストが低いアクセス・パスを使用して索引スキャンを行います。
/* フル・テーブル・スキャンを使用した問合せ */
SQL>SELECT seq FROM sample
2 WHERE col1 = 10;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF ’SAMPLE’
/* INDEXヒントを使用した問合せ(この例では索引スキップ・スキャンを行う) */
SQL>SELECT /*+ INDEX(sample col3_col1_ind) */ seq FROM sample
2 WHERE col1 = 10;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (BY INDEX ROWID) OF ’SAMPLE’
2 1 INDEX (SKIP SCAN) OF ’ COL3_COL1_IND’
INDEX_FFS
INDEX_FFS:フル・テーブル・スキャンまたは索引レンジ・スキャンではなく高速全索引スキャンを行います。
INDEX_FFS (表名 索引名 [ 索引名・・・ ] )
問合せに必要な全ての列を持つ索引が存在する場合、フル・テーブル・スキャンまたは索引レンジ・スキャンに代わり指定できます。
例)問合せで必要な全ての列を持つ索引 (COL3_COL1_IND) を使用した高速全索引スキャンを行う。
/* 索引レンジ・スキャンを使用した問合せ (シングル・ブロック読込み) */
SQL>SELECT seq FROM sample
2 WHERE col3 < 2;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 INDEX (RANGE SCAN) OF ’COL3_COL1_IND’ (NON-UNIQUE)
/* 高速全索引スキャンを使用した問合せ(マルチ・ブロック読込み) */
SQL>SELECT /*+ INDEX_FFS (sample col3_col1_ind) */ col1 FROM sample
2 WHERE col3 < 2;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 INDEX (FAST FULL SCAN) OF ’ COL3_COL1_IND’
ORDERED
ORDERED:FROM 句で指定された順番で結合を行います。
ORDERED
指定しない場合は、オプティマイザが結合順序を決定します。
例) FROM 句で指定されている順番でDEPT表、EMP表、SALGRADE表を結合する。
SQL>SELECT /*+ ORDERED */ ename,dname,grade
2 FROM dept, emp, salagrade
3 WHERE emp.deptno = dept.deptno
4 AND emp.sal BETWEEN salagrade.losal AND salagrade.hisal;
実行計画
-------------------------------------------------------------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 MERGE JOIN
2 1 SORT (JOIN)
3 2 HASH JOIN
4 3 TABLE ACCESS (FULL) OF ’DEPT’ ← 結合順序1
5 4 TABLE ACCESS (FULL) OF ’EMP’ ← 結合順序2
6 1 FILTER
7 6 SORT (JOIN)
8 7 TABLE ACCESS (FULL) OF ’SALGRADE’ ← 結合順序3
他のORDEREDヒントと組み合わせたヒント例(ヒントで指定された表は、結合順序が、その表の直前の表と結合)
/*+ ORDERED USE_NL (表名 [表名 表名・・・] ) */ :ネスティッド・ループ結合
/*+ ORDERED USE_MERGE (表名 [表名 表名・・・] ) */ :ソート/マージ結合
/*+ USE_HASH (表名 [表名 表名・・・] ) */ :ハッシュ結合 ( ORDEREDヒントと組み合わせて使用も可能)