【发布时间】:2010-10-06 15:09:57
【问题描述】:
如果我在Oracle的多个列中设置了一个主键,如果需要,我是否还需要创建索引?
我相信,当您在 one 列上设置主键时,您已将其编入索引;多列PK一样吗?
谢谢
【问题讨论】:
标签: oracle indexing primary-key multiple-columns
如果我在Oracle的多个列中设置了一个主键,如果需要,我是否还需要创建索引?
我相信,当您在 one 列上设置主键时,您已将其编入索引;多列PK一样吗?
谢谢
【问题讨论】:
标签: oracle indexing primary-key multiple-columns
不,不会为各个字段创建索引。
如果你有一个复合键 FieldA、FieldB、FieldC 和你
select * from MyTable where FieldA = :a
或
select * from MyTable where FieldA = :a and FieldB = :b
然后它将使用这个索引(因为它们是键中的前两个字段)
如果你有
select * from MyTable where FieldB = :b and FieldC = :c
在您使用部分索引而不是完整索引的情况下,通过索引跳过扫描、完整索引扫描或快速完整索引扫描,索引的使用效率会降低。
(感谢大卫·奥尔德里奇的更正)
【讨论】:
在 Oracle 中,这不是一个准确的说法。它仅在 (A,B,C) 上创建 1 个索引。不创建 (A,B) 和 (A) 索引。
【讨论】:
您可能需要根据您的主键结构在列上设置单独的索引。
复合主键和索引将按以下方式创建索引。假设我有 A、B、C 列,并且我在(A、B、C)上创建主键。这将导致索引
Oracle 实际上在任何最左边的列分组上创建一个索引。所以...如果您只想在 B 列上创建索引,则必须为其创建一个索引以及主键。
附:我知道 MySQL 表现出这种最左边的行为,我认为 SQL Server 也是最左边的
【讨论】:
主键意味着在主键列上创建composite unique index。
您可以使用名为INDEX SKIP SCAN 的特殊访问路径将此索引与不包括第一个索引列的谓词一起使用:
SQL> CREATE TABLE t_multiple (mul_first INTEGER NOT NULL, mul_second INTEGER NOT NULL, mul_data VARCHAR2(200))
2 /
Table created
SQL> ALTER TABLE t_multiple ADD CONSTRAINT pk_mul_first_second PRIMARY KEY (mul_first, mul_second)
2 /
Table altered
SELECT /*+ INDEX_SS (m pk_mul_first_second) */
*
FROM t_multiple m
WHERE mul_second = :test
SELECT STATEMENT, GOAL = ALL_ROWS
TABLE ACCESS BY INDEX ROWID SCOTT T_MULTIPLE
INDEX SKIP SCAN SCOTT PK_MUL_FIRST_SECOND
【讨论】:
如果列 a 仅具有低基数(例如 a 只有 2 个值),则将使用 B 选择索引。 一般来说,如果您想象列没有单独索引,而是列的索引连接(这并不完全正确,但它适用于第一个近似值),您可能已经猜到了这个答案。 所以不是a,b索引更像是a||b索引。
【讨论】:
如果您在 (A, B, C) 列上创建主键,那么 Oracle 默认会在 (A, B. C) 上创建唯一索引。您可以告诉 Oracle 使用不同的(不一定是唯一的)现有索引,如下所示:
alter table mytable add constraint mytable_pk
primary key (a, b, c)
using index mytable_index;
【讨论】:
主键只是一个(唯一的)索引,可能包含多个列
【讨论】:
您将获得一个跨多列的索引,这与在每一列上都有一个索引不同。
【讨论】: