質問
列 (A、B、C) にこの順序でインデックスを作成すると、(A)、(A と B)、または () のみを検索してもデータベースはそのインデックスを使用できると理解しています。 A と B と C)、ただし、(B)、(C)、または (B と C) だけを検索した場合はそうではありません。これは正しいです?
解決
実際には、述語が索引の先頭以外の列に配置されている場合に Oracle で使用できる索引ベースのアクセス方法が 3 つあります。
i) インデックススキップスキャン: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#PFGRF10105
ii) 高速フルインデックススキャン: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i52044
iii) インデックスフルスキャン: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#i82107
私は高速フルインデックススキャンが「実際に」行われているのをよく見てきましたが、すべてが可能です。
他のヒント
それは正しくありません。データを表すテスト ケースを考え出し、自分の目で確認することが常に最善です。Oracle SQL Optimizer を本当に理解したい場合は、Google Jonathan Lewis を参照してください。彼の本を読み、ブログを読み、Web サイトをチェックしてください。この人は素晴らしく、常にテスト ケースを生成します。
create table mytab nologging as (
select mod(rownum, 3) x, rownum y, mod(rownum, 3) z from all_objects, (select 'x' from user_tables where rownum < 4)
);
create index i on mytab (x, y, z);
exec dbms_stats.gather_table_stats(ownname=>'DBADMIN',tabname=>'MYTAB', cascade=>true);
set autot trace exp
select * from mytab where y=5000;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=10)
1 0 INDEX (SKIP SCAN) OF 'I' (INDEX) (Cost=1 Card=1 Bytes=10)
Oracle 8 までのバージョン SQL に最初の列が含まれていない限り、インデックスは使用されません。
Oracle 9i では、 スキャンインデックスへのアクセスをスキップ 機能が導入されました。これにより、Oracle CBO は、プレフィックス列が使用できない場合でもインデックスの使用を試みることができます。
スキップ スキャンの仕組みの概要は次のとおりです。 http://www.quest-pipelines.com/newsletter-v5/1004_C.htm