【问题标题】:Does making a primary key in multiple columns generate indexes for all of them?在多个列中创建主键是否会为所有列生成索引?
【发布时间】:2010-10-06 15:09:57
【问题描述】:

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

我相信,当您在 one 列上设置主键时,您已将其编入索引;多列PK一样吗?

谢谢

【问题讨论】:

    标签: oracle indexing primary-key multiple-columns


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 您可能希望更正索引使用部分——索引跳过扫描、完整索引扫描或快速完整索引扫描是允许索引用于所有这些情况的机制。跨度>
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      • (A、B、C)
      • (A,B)
      • (一)

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

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

      【讨论】:

      • Oracle 只会在 (A, B, C) 上创建一个索引。您可以创建其他索引,但 Oracle 需要并且只需要一个索引来强制执行主键。它必须包括 PK 的所有列。
      • WHERE 子句中只有 A 的查询可以轻松地使用 (A, B, C) 上的索引。 Oracle 曾经要求“最左边”使用索引,但新版本可以跳过最左边的索引 - 正如其他人所指出的那样。
      【解决方案4】:

      主键意味着在主键列上创建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
      

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          alter table mytable add constraint mytable_pk 
          primary key (a, b, c)
          using index mytable_index;
          

          【讨论】:

            【解决方案7】:

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

            【讨论】:

            • 索引不必是支持主键的唯一类型。在某些情况下(可延迟约束或物化视图上的 PK),实际上您肯定需要一个非唯一索引。
            【解决方案8】:

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

            【讨论】:

              猜你喜欢
              • 2013-08-02
              • 1970-01-01
              • 2015-01-23
              • 2015-11-03
              • 1970-01-01
              • 2014-12-15
              • 2017-02-28
              • 1970-01-01
              • 2012-05-09
              相关资源
              最近更新 更多