Oracle sqlplus
を使用しています。そして、私は次のクエリを持っています:
SELECT fooID from foo MINUS
SELECT fooID from bar;
2つのクラスター化されていないB +ツリーインデックスを作成しました。 1つはテーブルfooID
のフィールドfoo
にあり、もう1つはテーブルfooID
のフィールドbar
にあります。その後、両方のテーブルfoo
とbar
の統計を分析し、EXPLAIN PLAN ...
を使用してクエリの実行プランを確認します。しかし、私はこれを取得します:
SELECT STATEMENT
MINUS
SORT UNIQUE
INDEX FAST FULL SCAN FOO_INDEX
SORT UNIQUE
INDEX FAST FULL SCAN BAR_INDEX
どうしてそれも可能ですか? INDEX FAST FULL SCAN
を実行すると、インデックスはB +ツリーであるため、システムはタプルがソートされた状態に戻りませんか?なぜSORT UNIQUE
(データはすでにソートされている)を実行する必要があるのですか?
Oracleによると インデックスとインデックス構成テーブル アンダーフルインデックススキャン:フルインデックススキャンでは、データベースは全体を読み取りますインデックス順番に。
それでも、高速フルインデックススキャンでは、次のようになります。高速フルインデックススキャンは、データベースがインデックス自体のデータにアクセスするフルインデックススキャンです。テーブルにアクセスせずに、データベースは特定の順序なしでインデックスブロックを読み取ります。 (エンファシスマイン)
さて、おそらく問題は、オプティマイザーが_INDEX FAST FULL SCAN
_ではなく_INDEX FULL SCAN
_を選択した理由です。
後者の質問の答えへのヒントは、11.2.3.7高速フルインデックススキャンの下にあります:高速フルスキャンは、マルチブロックI/Oを使用でき、テーブルスキャンと同じように並行して実行できるため、通常の全索引スキャンよりも高速です。
Oracleがフルインデックススキャンを使用することを主張する場合は、/*+ index() */
ヒントを試してみてください。
_create table tq84_foo (
fooID number not null
);
create table tq84_bar (
fooID number not null
);
create unique index ix_foo on tq84_foo(fooID);
create unique index ix_bar on tq84_bar(fooID);
explain plan for
select /*+ index(f ix_foo) */fooID from tq84_foo f
MINUS
select /*+ index(b ix_bar) */ fooID from tq84_bar b;
select * from table(dbms_xplan.display);
_
その結果
_------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 4 (75)| 00:00:01 |
| 1 | MINUS | | | | | |
| 2 | SORT UNIQUE NOSORT| | 1 | 13 | 2 (50)| 00:00:01 |
| 3 | INDEX FULL SCAN | IX_FOO | 1 | 13 | 1 (0)| 00:00:01 |
| 4 | SORT UNIQUE NOSORT| | 1 | 13 | 2 (50)| 00:00:01 |
| 5 | INDEX FULL SCAN | IX_BAR | 1 | 13 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------
_