実行計画を見てるとでてくる INDEX UNIQUE SCAN と INDEX RANGE SCAN ってなんだ?
11.5.3.2 索引一意スキャン
このスキャンは1つのROWIDしか戻しません。単一行にしかアクセスしないことが保証されているUNIQUE制約またはPRIMARY KEY制約が文に存在する場合、Oracleは一意スキャンを実行します。
例11-2「EXPLAIN PLAN出力」では、jobs表およびdepartments表で、それぞれjob_id_pk索引とdept_id_pk索引を使用して索引スキャンが実行されます
問合せオプティマイザ
11.5.3.3 索引レンジ・スキャン
索引レンジ・スキャンは、選択性の高いデータにアクセスする共通の操作です。このスキャンは、境界(両側で境界付き)スキャンまたは非有界(片側または両側で)スキャンとすることができます。データは、索引列の昇順に戻されます。同じ値を持つ複数の行は、ROWIDで昇順にソートされます。
データを一定順序でソートする必要がある場合は、ORDER BY句を使用し、索引には依存しません。索引を使用してORDER BY句を満たすことができる場合、オプティマイザはこのオプションを使用し、ソートを回避します。
問合せオプティマイザ
プライマリキーもしくはユニークインデックスになっているカラムに対してイコール検索すると、INDEX UNIQUE SCAN が使われるみたい。
普通のインデックスになっているカラムに対してイコール検索した場合と内部動作がどのように異なるんだろ?
またこんど、続きを調べよ。
ちょっとごちょごちょしてみた。
SQL> conn scott/tiger SQL> @?/rdbms/admin/utlxplan.sql SQL> explain plan for select ename from emp where empno = 7369; SQL> select * from table((dbms_xplan.display(null, null))); PLAN_TABLE_OUTPUT --------------------------------------------------------------------------- --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | | | | |* 2 | INDEX UNIQUE SCAN | PK_EMP | | | | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- PLAN_TABLE_OUTPUT --------------------------------------------------------------------------- 2 - access("EMP"."EMPNO"=7369) Note: rule based optimization 15 rows selected. SQL> explain plan for select ename from emp where ename = 'NEO'; SQL> select * from table((dbms_xplan.display(null, null))); PLAN_TABLE_OUTPUT -------------------------------------------------------------------- -------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | -------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | |* 1 | TABLE ACCESS FULL | EMP | | | | -------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- PLAN_TABLE_OUTPUT -------------------------------------------------------------------- 1 - filter("EMP"."ENAME"='NEO') Note: rule based optimization 14 rows selected. SQL> create index scott.emp_ename_idx on scott.emp (ename); SQL> explain plan for select ename from emp where ename = 'NEO'; SQL> select * from table((dbms_xplan.display(null, null))); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------- ----------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ----------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | |* 1 | INDEX RANGE SCAN | EMP_ENAME_IDX | | | | ----------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- PLAN_TABLE_OUTPUT ----------------------------------------------------------------------- 1 - access("EMP"."ENAME"='NEO') Note: rule based optimization 14 rows selected. SQL> drop index emp_ename_idx; SQL> create unique index scott.emp_ename_idx on scott.emp (ename); SQL> explain plan for select ename from emp where ename = 'NEO'; SQL> select * from table((dbms_xplan.display(null, null))); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------- ----------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ----------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | |* 1 | INDEX UNIQUE SCAN | EMP_ENAME_IDX | | | | ----------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- PLAN_TABLE_OUTPUT ----------------------------------------------------------------------- 1 - access("EMP"."ENAME"='NEO') Note: rule based optimization 14 rows selected. SQL> select * from v$version; BANNER ---------------------------------------------------------------- Oracle9i Enterprise Edition Release 9.2.0.7.0 - 64bit Production PL/SQL Release 9.2.0.7.0 - Production CORE 9.2.0.7.0 Production TNS for Solaris: Version 9.2.0.7.0 - Production NLSRTL Version 9.2.0.7.0 - Production
[参考]
SQL文の実行計画を見る - bnote
スキーマ・オブジェクト
問合せオプティマイザ
Schema Objects