覆盖指数安全地取代较小的覆盖指数吗?

时间:2009-09-23 22:04:43

标签: sql indexing covering-index

例如:

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都冗余?

5 个答案:

答案 0 :(得分:3)

一般而言 - 这在服务器与服务器之间有所不同 - 覆盖索引将涵盖较小的索引选择。

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

例如,您不能保证覆盖索引为b,c。

答案 1 :(得分:2)

是的,大部分都是。

但是,IX_ABCD作为IX_BCD的替代品并不是非常有用。

但有一点需要注意:索引仍然可能需要磁盘读取,因此如果C和D爆炸索引的大小,在查找IX_ABCD中的A,B时会出现一些效率低下的问题在IX_AB。

但是,单独维护IX_AB所带来的额外性能可能会超过这种差异。

答案 2 :(得分:1)

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

从表中选择*,其中A = 1

从表中选择*,其中A = 1且B = 1

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

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

从表中选择*,其中B = 1

从表中选择*,其中C = 1

从表中选择*,其中B = 1且C = 1

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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