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 也有同样的问题。
您问题的关键是“基数”列。您只有五行被估计为表返回。
Oracle 有两种执行计划可供选择:
Oracle 得出结论,对于 5 条记录,第一种方法更快。如果将更多数据加载到表中,您应该会看到执行计划发生变化。或者,如果您使用的是select last_name
而不是select *
,那么 Oracle 很可能会选择索引。