为什么Oracle不对非唯一索引使用索引完全扫描?

问题描述 投票:0回答:1

我在HR模式中创建了employees表的副本。然后在employee_id列上添加一个非唯一索引。

create table employees1 as select * from employees;
create index temp_idx on employees1(employee_id);

然后检查其执行计划“从雇员中选择employee_id;”,它执行了全表扫描,成本为3。但是,当我创建一个唯一索引时,它执行了索引全扫描,成本为1。

据我所知,oracle如何创建唯一索引和非唯一索引是相同的。因此,两个索引中的叶子数等应相同。因此,在这种情况下,尽管它可以选择具有非唯一索引的索引全扫描并将成本降低到1,但为什么选择全表扫描并导致更糟糕的计划呢?顺便说一句,创建表格后,我没有删除或插入任何行。

oracle database-performance sqlperformance sql-tuning
1个回答
0
投票

您在存在唯一索引的情况下对执行计划的看法是完全错误的。 (我刚刚检查了机器-即使使用唯一索引,Oracle仍会执行完整扫描。)

这很合理。无论索引是否唯一,当EMPLOYEE_ID为NULL时,索引都不会存储任何内容。如果希望Oracle执行索引扫描,则必须告诉Oracle列为NOT NULL(当列为primary key时会自动发生-也许您将其与“唯一索引”混淆了),或者必须“选择employee_id ... WHERE EMPLOYEE_ID不为空”。您可能知道“非空”条件对于所有行都是正确的,但是Oracle直到从表中读取所有数据后才知道。如果明确声明只需要非空值,则Oracle知道它可以使用索引。 (同样,索引是否唯一也没关系!)

© www.soinside.com 2019 - 2024. All rights reserved.