我必须查询一个合理的大表(450M行),这些表是分区和索引的。
假设这个结构:
该表在load_num上进行了分区,大约3个负载进入一个分区。 (所以load_num在分区中不是唯一的)
有三个索引,其中两个有load_num,cust_id是前两列(int那个顺序)
当我发出此查询时:
select *
from fact
where load_num = 100
and cust_id = 12345
返回需要很长时间,所以我点击了解释计划并获得正确的分区,然后对其进行全表扫描。
为什么oracle不使用其中一个索引在分区上进行ROWID扫描来获取行?
cust_id应该相当独特,表格中的统计信息是最新的。我们在10g Entreprise上。
来自MS SQL,所以我还没有达到Oracle的速度。
提前致谢,
格特 - 扬
**编辑:一些不确定的DDL:
CREATE TABLE FACT
(
LOAD_NUM NUMBER
... columns ..
, CUSTOMER_ID VARCHAR2(20 BYTE)
.. columns
)
TABLESPACE "TS_A"
PCTFREE 0
INITRANS 1
STORAGE
(
BUFFER_POOL DEFAULT
)
PARALLEL 12
PARTITION BY LIST (LOAD_NUM)
(
PARTITION FACT_46 VALUES (46) TABLESPACE FACT_PART_DATA_46
COMPRESS
, PARTITION FACT_52 VALUES (52) TABLESPACE FACT_PART_DATA_52
COMPRESS
, PARTITION FACT_56 VALUES (56) TABLESPACE FACT_PART_DATA_56
COMPRESS
... more partitions ...
)CREATE INDEX SOMESCHEMA.FACT_IDX2 ON SOMESCHEMA.FACT (LOAD_NUM ASC, CUSTOMER_ID ASC, OUTSTANDING_ID ASC)
LOCAL
(
PARTITION FACT_DATA_46
LOGGING
TABLESPACE "FACT_DATA_46"
PCTFREE 10
INITRANS 2
STORAGE
(
INITIAL 65536
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
)
NOCOMPRESS
, PARTITION FACT_DATA_52
LOGGING
TABLESPACE "FACT_DATA_52"
PCTFREE 10
INITRANS 2
STORAGE
(
INITIAL 65536
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
)
NOCOMPRESS
,
... etc etc ..
)
答案 0 :(得分:3)
为什么oracle不使用其中一个索引在分区上进行ROWID扫描来获取行?
很难确切说明为什么Oracle
不使用索引,因为您的设置中没有任何内容可以阻止它这样做。
最有可能的是,cust_id
分布存在偏差,因此Oracle认为PARTITION SCAN
的效率更高。
请您尝试明确添加提示:
SELECT /*+ INDEX (f FACT_IDX2) */
*
FROM fact f
WHERE load_num = 100
AND cust_id = 12345
确保在计划中使用它并检查此方法是否真的更快。
另外,请发布此查询返回的内容:
SELECT COUNT(*), COUNT(DECODE(cust_id, 12345, 1))
FROM fact f
WHERE load_num = 100