9

如果我在 Oracle 的多个列中设置主键,是否还需要在需要时创建索引?

我相信,当您在列上设置主键时,您会为其编制索引;多列 PK 是否相同?

谢谢

4

8 回答 8

12

不,不会为各个字段创建索引。

如果你有一个复合键 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

在您使用部分索引而不是完整索引的情况下,通过索引跳过扫描、完整索引扫描或快速完整索引扫描,索引的使用效率会降低。

(感谢大卫奥尔德里奇的更正)

于 2009-02-10T12:12:34.133 回答
4

如果您在 (A, B, C) 列上创建主键,那么 Oracle 默认会在 (A, B. C) 上创建唯一索引。您可以告诉 Oracle 使用不同的(不一定是唯一的)现有索引,如下所示:

alter table mytable add constraint mytable_pk 
primary key (a, b, c)
using index mytable_index;
于 2009-02-10T12:17:59.613 回答
2

您将在多个列上获得一个索引,这与在每一列上都有一个索引不同。

于 2009-02-10T12:09:47.323 回答
2

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
于 2009-02-10T13:17:01.000 回答
0

主键只是一个(唯一)索引,可能包含多个列

于 2009-02-10T12:10:23.453 回答
0

对于 B,如果列 a 仅具有低基数(例如 a 只有 2 个值),则将使用选择索引。一般来说,如果您想象列没有单独索引,而是列的索引连接(这并不完全正确,但它适用于第一个近似值),您通常可以猜到这个答案。所以它不是 a, b 索引它更像是 a||b 索引。

于 2009-02-10T12:44:05.713 回答
0

您可能需要根据您的主键结构在列上设置单独的索引。

复合主键和索引将按以下方式创建索引。假设我有 A、B、C 列,并且 ia 在(A、B、C)上创建主键。这将导致索引

  • (甲、乙、丙)
  • (甲,乙)
  • (一种)

Oracle 实际上在任何最左边的列分组上创建一个索引。所以...如果您只想在 B 列上建立索引,则必须为其创建一个索引以及主键。

PS我知道MySQL表现出这种最左边的行为,我认为SQL Server也是最左边的

于 2009-02-10T23:02:36.350 回答
0

在 Oracle 中,这不是一个准确的说法。它仅在 (A,B,C) 上创建 1 个索引。不创建 (A,B) 和 (A) 索引。

于 2010-03-11T19:02:45.353 回答