试图从 Oracle 中的这个观察中弄清楚一些意义。
询问:SELECT ... FROM MY_TABLE WHERE PART_KEY=x and DT_KEY between 20120101 and 20120731
在 PART_KEY/DT_KEY 上使用索引扫描,即使自动跟踪显示索引扫描命中的块(一次一个,单块读取)比完整扫描命中的块(在单个多块读取中)更多。统计数据是最新的。
奇怪的是,如果我尝试在不分区的情况下使用同一个表和索引的副本,在使用索引之前似乎有更高的选择性阈值——我上面给出的范围进行了全面扫描,而且只有一个非常窄的范围的值DT_KEY between d1 and d2
将使用索引。我验证了该索引也将用于非分区情况,但 Oracle 似乎更倾向于进行全面扫描。
Oracle 如何决定使用索引而不是全扫描,我还应该查看什么?统计数据是最新的,因为我立即收集了它们。
表结构
CREATE TABLE MY_TABLE (
PART_KEY NUMBER(10) NOT NULL,
DT_KEY NUMBER(8) NOT NULL,
...
)
PARTITION BY LIST(PART_KEY) (
PARTITION P1 ...
)
AS SELECT .... FROM [source table]
CREATE INDEX MY_INDEX ON MY_TABLE(PART_KEY, DT_KEY) LOCAL;
EXEC DBMS_STATS.GATHER_TABLE_STATS('[USERNAME]', 'MY_TABLE');