未使用分区表上的索引
我必须查询一个相当大的表(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 Enterprise。
来自 MS SQL,所以我还没有跟上 Oracle 的速度。
提前致谢,
Gert-Jan
** 编辑:一些匿名 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 ..
)
I have to query a reasonably large table (450M rows) that is partitoned and indexed.
suppose this structure:
- load_num(int)
- cust_id(int)
- ... some more columns ...
The table is partitioned over load_num, around 3 loads go into one partition. (so load_num is not unique within a partition)
There there are three indexes, two of them who have load_num, cust_id as the first two columns (int that order)
When I issue this query:
select *
from fact
where load_num = 100
and cust_id = 12345
It takes quite long to return, so I hit explain plan and it gets the right partition but then does a FULL table scan on it.
Why isn't oracle using one of the two indexes to do a ROWID scan on the partition to get the rows?
The cust_id should be fairly unique and the statistics on the table are up to date. We're on 10g Entreprise.
Came from MS SQL so I'm not up to speed with Oracle yet.
Thanks in advance,
Gert-Jan
** EDIT: Some anonimized 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 ..
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很难确切地说明为什么
Oracle
不使用索引,因为您的设置中没有任何内容可以阻止它这样做。最有可能的是,cust_id 分布是倾斜的,因此 Oracle 认为 PARTITION SCAN 更有效。
您能否尝试明确添加提示:
确保在计划中使用它并检查此方法是否确实更快。
另外,请发布此查询返回什么:
It's hard to tell exactly why
Oracle
doesn't use the index, since there is nothing in your setup that would prevent it from doing so.Most probably,
cust_id
distribution is skewed so that Oracle considersPARTITION SCAN
more efficient.Could you please try adding the hint explicitly:
Make sure that it's used in the plan and check that this method is really faster.
Also, please post what does this query return: