【问题标题】:Do covering indices safely replace smaller covering indices?覆盖指数是否可以安全地替代较小的覆盖指数?
【发布时间】:2009-09-23 22:04:42
【问题描述】:

例如:

Given columns A,B,C,D,

IX_A is an index on 'A'

IX_AB is a covering index on 'AB'

IX_A 可以安全地移除,因为它是多余的:IX_AB 将被用来代替它。 我想知道这是否概括:

如果我有:

IX_AB
IX_ABC
IX_ABCD

等等,

还可以安全地删除较小的索引吗? 即 IX_ABC 是否使 IX_AB 冗余,IX_ABCD 是否使 IX_AB 和 IX_ABC 都冗余?

【问题讨论】:

    标签: sql indexing covering-index


    【解决方案1】:

    一般来说——这因服务器而异——覆盖索引将覆盖索引的较小选择。

    因此,如果您有一个涵盖 a、b、c 的索引,通常会自动为您提供一个涵盖 a、a、b 的索引。

    不保证您拥有例如 b、c 的覆盖索引。

    【讨论】:

    • 肯定不会有 BC 的覆盖索引。但是 +1 - 任何不使用 AB_IDX 来查找 A 的 DBMS 都会很差。
    • 我似乎记得一些较小的 DBMS,它们在 A、B、C 覆盖索引上授予 B、C。但是,SQL Server 或 Oracle 肯定不是这种情况。
    • 我认为您可能在谈论索引搜索与索引扫描。如果查询中使用了前导列,则将执行索引查找。如果列在索引中,而不是前导列,将使用索引扫描(直接到叶子)。
    【解决方案2】:

    是的,大部分情况下。

    但是,IX_ABCD 作为 IX_BCD 的替代品并没有太大帮助。

    但是有一个警告:索引仍然可能需要磁盘读取,因此如果 C 和 D 爆炸了索引的大小,那么在 IX_ABCD 中查找 A、B 时会出现一些效率低下,而在查找时不会发生这种情况在 IX_AB 中。

    但是,单独维护 IX_AB 对性能的额外影响可能超过了这种差异。

    【讨论】:

    • 关于“差异可能超过”:这取决于您的读/写比率。在极端情况下,静态表有很多索引没有性能影响。但是磁盘读取 +1 - 这是一个好点。
    【解决方案3】:

    重要的是索引中的前导列。如果您有索引 IX_ABCD,则以下查询将使用该索引:

    从 A = 1 的表中选择 *

    从 A = 1 和 B = 1 的表中选择 *

    从 A = 1 且 B = 1 且 C = 1 的表中选择 *

    但是,以下内容很可能不会使用索引(至少不是您想要的):

    从 B = 1 的表中选择 *

    从 C = 1 的表中选择 *

    从 B = 1 和 C = 1 的表中选择 *

    重要的是使用了前导列。因此,创建索引时列的顺序很重要。

    【讨论】:

      【解决方案4】:

      不一定。虽然 (A, B, C) 上的索引可用于 A 上的过滤谓词或 A 上的排序请求或 A 上的连接条件,但这并不一定意味着单独的索引 (A) 是无用的.如果 (A, B, C) 上的索引比 (A) 显着,那么单独对 A 进行范围扫描将节省大量 I/O,因为它必须读取更少的页面(更窄的索引)。

      ut 我认为这将是例外而不是规则。一般来说,如果 (A, B) 上存在另一个索引,则删除 A 上的索引是安全的。请注意, (A,B) 上的索引不满足 B 上的任何过滤,因此,仅当最左边的列相同时才能安全删除。一些数据库具有“跳过扫描”运算符,可以使用 (A,B) 上的索引来查找 B,但这是一个非常狭窄的边界情况。

      【讨论】:

        【解决方案5】:

        最好不要对数据库引擎内部做任何假设,并实际检查正在使用的实际查询计划。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-04
          • 2013-12-29
          相关资源
          最近更新 更多