【发布时间】:2014-05-30 11:13:38
【问题描述】:
我是 Oracle 的新手,虽然我已经相当广泛地使用 SQL Server,但我不需要深入研究数据库设计的细节……特别是索引。因此,我花了很多时间阅读有关索引的教程......无论是概念上的还是特定于 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
但是,当我运行查询以选择具有特定 LAST_NAME 的人时,LAST_NAME 索引似乎被忽略了。
select * from TBL_PERSON where LAST_NAME = 'Stenstrom'
为什么不使用 IDX_LAST_NAME?对于它的价值,我对复合索引 IDX_PERSON_NAME 有同样的问题。
【问题讨论】:
-
与您当前的问题没有直接关系,但有些事情可以让您更轻松地过渡到 Oracle... 永远不要在
SYS或SYSTEM架构中创建自己的对象,为你的对象。SYS和SYSTEM由 Oracle 保留,功能有时在此处的行为会有所不同。ROWID是 Oracle 中的保留字,指的是行的物理地址,而不是主键值。在新开发中很少会想要使用NVARCHAR2数据类型,选择Unicode 字符集并改用VARCHAR2。 -
此外,Oracle 没有聚集索引之类的东西,因此将索引称为“非聚集”只会造成混淆。 Oracle 中最接近聚集索引的是索引组织表——如果您谈论“非聚集索引”,人们可能会认为您有一个索引组织表,而不是您实际创建的堆组织表.
-
表
tbl_person包含多少行?LAST_NAME上的查询返回了多少? -
@a_horse_with_no_name (America! nice:) ) - 我已将记录增加到大约 25 条以上。在此特定查询中,将返回 8 条记录。
-
对于 25 行中的 8 行,使用索引没有意义。这 25 行可能都驻留在同一个数据库块上,这意味着全表扫描只是一次 I/O 操作——最多 2 次。对较大表的索引扫描通常仅在查询返回不超过约 0 时才有效。总行数的 10-15%。