1

例如:

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 都变得多余?

4

5 回答 5

3

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

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

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

于 2009-09-23T22:08:34.287 回答
2

是的,在大多数情况下。

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

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

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

于 2009-09-23T22:09:02.080 回答
1

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

从 A = 1 的表中选择 *

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

select * from table where A = 1 and B = 1 and C = 1

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

从 B = 1 的表中选择 *

从 C = 1 的表中选择 *

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

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

于 2009-09-23T22:09:30.603 回答
0

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

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

于 2009-09-23T22:14:31.467 回答
0

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

于 2009-09-23T23:19:50.440 回答