未使用分区表的索引

时间:2011-01-12 10:56:09

标签: oracle optimization indexing partitioning

我必须查询一个合理的大表(450M行),这些表是分区和索引的。

假设这个结构:

  • load_num(int)的
  • 的cust_id(int)的
  • ......更多专栏......

该表在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 ..
)

1 个答案:

答案 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