oracle 查询未使用索引

Gar*_*rom 3 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")
   )
Run Code Online (Sandbox Code Playgroud)

如您所见,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")
Run Code Online (Sandbox Code Playgroud)

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

select * from TBL_PERSON where PERSON_ID = 21
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

select * from TBL_PERSON where LAST_NAME = 'Stenstrom'
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

为什么不使用 IDX_LAST_NAME?值得一提的是,我对复合索引 IDX_PERSON_NAME 也有同样的问题。

Gor*_*off 5

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

Oracle 有两种执行计划可供选择:

  1. 加载数据页。扫描数据页上的五个记录并选择符合条件的记录。
  2. 加载索引并扫描它以查找匹配项。然后加载数据页面并查找匹配的记录。

Oracle 得出结论,对于 5 条记录,第一种方法更快。如果将更多数据加载到表中,您应该会看到执行计划发生变化。或者,如果您使用的是select last_name而不是select *,那么 Oracle 很可能会选择索引。

  • +1 但值得注意的是,基数 5 不是 Oracle 对表中总行数的估计,而是过滤后返回的行数的估计。 (2认同)