PSI Labs RSS feed

Oracle:複数のインデックスヒントを記述した場合の動作

こんにちは。shintaniです。

WS000000.JPG

こういった画面があり、どの項目も任意入力であるとします。
そしてテーブルの各列には個別にインデックスが貼られているとします。

create table TBL_TEST
(   col1_yyyymmdd     VARCHAR2(8)
   ,col2_unique       VARCHAR2(20)
   ,col3_non_unique   VARCHAR2(10)
);

create index  IND_TEST_col1  ON  TBL_TEST(col1_yyyymmdd) TABLESPACE IDX_TBS;
create index  IND_TEST_col2  ON  TBL_TEST(col2_unique) TABLESPACE IDX_TBS;
create index  IND_TEST_col3  ON  TBL_TEST(col3_non_unique) TABLESPACE IDX_TBS;

この場合に「どのインデックスが使われるか?」は、統計情報を適切に取得したうえでオプティマイザに任せるのが基本です。
しかし、ヒント句を付けることによって制御しなければならなくなった場合はどうなるでしょうか?

値の絞り込み度は
col2_unique > col3_non_unique > col1_yyyymmdd
とし、インデックスの優先度もこの順とします。

この場合、「もっとも優先度が高いもの1つだけINDEXヒントで指定する」とすると、条件判断ロジックをどこかに組み込まないといけません。
これは面倒です。特に条件が多くなればなるほど。

しかし、何らかの法則があればそれに従って検索条件に設定されたものを無条件に設定することで対応できます。

select 
  /*+ INDEX(T IND_TEST_col2) */
  /*+ INDEX(T IND_TEST_col3) */
  /*+ INDEX(T IND_TEST_col1) */
     *
  from 
     TBL_TEST T
where 
   col1_yyyymmdd between  '20150201' and   '20150301'
and
   col2_unique = '201502110000000475'
and
   col3_non_unique = '0000000475'
;

上記の場合、どのインデックスが使われるでしょうか?
検証過程を省略して結果だけ書くと下記のようになります。


書いたものの中で一番最初だけ有効となる。
もしそれが検索条件に無いなどで使えない場合、INDEXヒント無しと同じ。

つまり上記のように優先して使いたいINDEXヒントを上に書けば良いです。

なお下記のようにINDEXヒントの中に併用不可のインデックスを複数指定した場合は、統計情報から判断された一番優先度が高いものが選択されます

select 
   /*+ INDEX(T IND_TEST_col1  IND_TEST_col2 IND_TEST_col3 ) */
   *
from 
   TBL_TEST   T
where 
   col1_yyyymmdd between  '20150201' and   '20150301'
and
   col2_unique = '201502110000000475'
and
   col3_non_unique = '0000000475'
;

なお、以上の検証は Oracle12.1.0.2 で行いました。

ではでは。