次のようなパーティション分割されたテーブルがあります。
create table demo (
ID NUMBER(22) not null,
TS TIMESTAMP not null,
KEY VARCHAR2(5) not null,
...lots more columns...
)
パーティションはTS
列にあります (1 年に 1 つのパーティション)。
タイムスタンプを介して多くの検索を行うため、複合インデックスを作成しました。
create index demo.x1 on demo (ts, key);
クエリは次のようになります。
select *
from demo t
where t.TS = to_timestamp('2009-06-30 07:47:57', 'YYYY-MM-DD HH24:MI:SS')
私も追加しようとしましand t.KEY = '00101'
たが、それは役に立ちません。
しかし、それとEXPLAIN PLAN
言う:TABLE ACCESS
FULL
# Operation Options Object Mode Cost Bytes Cardinality
0 SELECT STATEMENT ALL_ROWS 583804 287145 2127
1 PARTITION RANGE ALL 583804 287145 2127
2 TABLE ACCESS FULL HEADER ANALYZED 583804 287145 2127
インデックスについては言及されていません。何が間違っている可能性がありますか?
[編集] 何らかの理由で、オラクルは操作のコストを完全に誤って計算しました。そのテーブルには 1 億 1,200 万行あります。1 つのパーティションのフル スキャンのコストは、600,000 ではなく、2,000 万である必要があります。そのため、オプティマイザのヒントも無視されます。
[EDIT2] テスト中に、この不可解な結果に出くわしました。これを実行するとselect
:
select tx_ts
from kt.header
where tx_ts = to_timestamp('2009-06-30 07:47:57', 'YYYY-MM-DD HH24:MI:SS')
この EXPLAIN PLAN を取得します。
0 SELECT STATEMENT ALL_ROWS 152 15616 1952
1 PARTITION RANGE ALL 152 15616 1952
2 INDEX FAST FULL SCAN HEADERX2 ANALYZED 152 15616 1952
そのため、結果として索引付けされた列に自分自身を制限するとselect
、Oracle は索引を使用することを決定します。すべての列を取得したい場合は、完全なテーブル スキャンを待つ必要があります。何が起きてる?
[EDIT2] 見つけました。以下の私の答えを見てください。