oracle查询不使用索引

时间:2014-04-15 21:30:05

标签: sql oracle indexing

我是Oracle的新手,虽然我已经广泛使用了SQL Server,但我没有必要深入研究数据库设计的细节......特别是INDEXES。所以我花了很多时间坐在索引教程上......无论是概念还是Oracle特定的。

为了将我的理解付诸实践,我设置了一个非常简单的表,其中包含一些基本索引。

CREATE TABLE "SYSTEM"."TBL_PERSON" 
   (    
        "PERSON_ID" NUMBER(10,0) NOT NULL ENABLE, 
        "FIRST_NAME" NVARCHAR2(120) NOT NULL ENABLE, 
        "MIDDLE_NAME" NVARCHAR2(120), 
        "LAST_NAME" NVARCHAR2(120) NOT NULL ENABLE, 
        "DOB" DATE NOT NULL ENABLE, 
        "IS_MALE" NCHAR(1) DEFAULT 'T' NOT NULL ENABLE,
        CONSTRAINT "TBL_PERSON_PK" PRIMARY KEY ("PERSON_ID")
   )

正如您所看到的,PERSON_ID字段包含表中每条记录的唯一ROWID,并且是一个自动递增的主键。

(请不要挂断错过SQL,除非它与INDEXES的问题无关。我试图从DDL中只选择相关的SQL并且可能错过了一些项目。那里有很多东西我认为这与此问题无关,所以我试图将其删除)

我在表上创建了一些额外的非聚集索引。

CREATE INDEX "SYSTEM"."IDX_LAST_NAME" ON "SYSTEM"."TBL_PERSON" ("LAST_NAME") 
CREATE INDEX "SYSTEM"."IDX_PERSON_NAME" ON "SYSTEM"."TBL_PERSON" ("FIRST_NAME", "LAST_NAME")

当我在下面的SQL上运行“解释计划”时,我会收到PK索引按预期使用的通知。

select * from TBL_PERSON where PERSON_ID = 21

enter image description here

但是,当我运行查询以选择具有特定LAST_NAME的人时,LAST_NAME索引似乎会被忽略。

select * from TBL_PERSON where LAST_NAME = 'Stenstrom'

enter image description here

为什么不使用IDX_LAST_NAME?对于它的价值,我对复合索引IDX_PERSON_NAME也有同样的问题。

1 个答案:

答案 0 :(得分:4)

您问题的关键是“基数”一栏。您只有五行估计为表格返回。

Oracle可以在两个执行计划之间进行选择:

  1. 加载数据页面。扫描数据页面上的五个记录,然后选择符合条件的记录。
  2. 加载索引并扫描以进行匹配。然后加载数据页面并查找匹配的记录。
  3. 甲骨文已经得出结论,对于五条记录,第一种方法更快。如果将更多数据加载到表中,您应该看到执行计划发生了变化。或者,如果您有select last_name而不是select *,那么Oracle可能会很好地选择索引。