我有一个这样的分区表:
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')
我也尝试添加 和 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万,而不是60万。这就是它甚至忽略优化器提示的原因。
[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] 找到了;请参阅下面的答案。
最佳答案
好吧,这是我的错误:该列的类型是 DATE
,而不是 TIMESTAMP
。由于我使用了 to_timestamp()
,因此 Oracle 无法使用索引。
关于Oracle 拒绝使用索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1573312/