本件のタイトルが意味するところは2つあり、
1つはインデックスを作成してみたはいいもののそのインデックスが
オプティマイザで有効になっているか否かを確認する。
もう1つは高速化を狙ったインデックスが意味を成していないのではないか、というものである。
前者を確認するにはSQLの冒頭に「explain plan for」と記述して、
その後にOracleの実行計画を参照する。
SQL> explain plan for
2 select
3 *
4 from
5 ZZZ_TABLE
6 where
7 CLM01 = '001' AND
8 CLM02 = '1';
解析されました。
SQL>
SQL> @C:\oracle\product\10.2.0\db_2\RDBMS\ADMIN\UTLXPLS.SQL
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 2565712139
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 510 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| ZZZ_TABLE | 1 | 510 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | ZZZ_TABLEI0 | 1 | | 0 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
---------------------------------------------------
2 - access("CLM01"='001' AND "CLM02"=1)
14行が選択されました。
上記の例を見ると、実行計画に「INDEX UNIQUE SCAN」とあるが、
これはインデックスを利用したことを表していて、
これが「TABLE ACCESS FULL」となっていると、インデックスが利用されずに
テーブルを総なめしているということになる。
Oracleのオプティマイザの判断により、インデックスを利用したSQLを発行したにも
関わらずそのような結果になることもある。
では、Oracleのオプティマイザのジャッジは正しかったのか。
ヒント文を利用すれば、明示的にインデックス検索や全表検索が可能となる。
select
/*+ INDEX(ZZZ_TABLE ZZZ_TABLEI0) */ *
from
ZZZ_TABLE
where
CLM01 = '001' AND
CLM02 = '1';
select
/*+ FULL ZZZ_TABLE */ *
from
ZZZ_TABLE
where
CLM01 = '001' AND
CLM02 = '1';