我有一个这样的分区表:
create table demo (
ID NUMBER(22) not null,
TS TIMESTAMP not null,
KEY VARCHAR2(5) not null,
...lots more columns...
)
分区在TS
列上(每年一个分区)。
由于我通过时间戳进行了很多搜索,因此我创建了一个组合索引:
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
没有提到指数。有什么问题?
[编辑] 出于某种原因,Oracle 完全错误地计算了该操作的成本。我在该表中有 1.12 亿行。完整扫描单个分区的成本应该是 2000 万,而不是 600'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')
我得到这个解释计划:
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] 找到它;请参阅下面的答案。