如果A,B,C上有索引,A,B上的索引是多余的吗?

时间:2012-12-09 20:11:33

标签: sql sql-server indexing

作为一名DBA拥有多年的经验,我相信我知道这个问题的答案,但我认为检查我的基础绝对不会伤害。

使用SQL Server,假设我的表具有列A和列B的索引,以及列AB上的第二个索引,以及C,删除第一个索引是否安全,因为第二个索引基本上可以满足从第一个索引中受益的查询?

5 个答案:

答案 0 :(得分:29)

这取决于,但答案通常是'是的,你可以将索引放在(A,B)上。

反对案例(你不会将索引放在(A,B)上)是指(A,B)上的索引是强制执行约束的唯一索引;那么你不想把索引放在(A,B)上。 (A,B,C)上的索引也可以是唯一的,但唯一性是多余的,因为(A,B)组合因其他索引而是唯一的。

但是在没有这种异常情况的情况下(例如,如果(A,B)和(A,B,C)都允许重复条目),那么(A,B)索引在逻辑上是多余的。但是,如果列C是'宽'(也许是CHAR(100)列),而A和B很小(比如INTEGER),则(A,B)索引比(A,B,C)更有效。 )index因为你可以获得每页(A,B)索引读取的更多信息。因此,即使(A,B)是多余的,也可能值得保留。您还需要考虑表格的波动性;如果表很少变化,额外的索引并不重要;如果表变化很大,额外的索引会减慢对表的修改。这是否重要难以猜测;你可能需要进行性能测量。

答案 1 :(得分:11)

第一个索引涵盖查询AA,B的查询,第二个索引可用于覆盖查询AA,B或{的查询{1}}这显然是第一种情况的超集。

如果A,B,C非常宽,则C上的索引可能仍然有用,因为它可以满足某些查询较少的查询。

e.g。如果A,BC列,则以下查询可能会从较窄的索引中获益。

char(800)

答案 2 :(得分:7)

是的,这是一种常见的优化方式。任何可以从A,B上的索引中受益的查询也可以从A,B,C上的索引中受益。

在MySQL社区中,甚至还有一个工具可以在整个模式中搜索冗余索引:http://www.percona.com/doc/percona-toolkit/pt-duplicate-key-checker.html

可能的异常情况是,如果A,B上的索引更紧凑并且使用频率更高,并且您想控制哪个索引保持在内存中加载。

答案 3 :(得分:4)

我所想的很多都是乔纳森在之前的回答中写的。独特性,更快的工作,以及我认为他错过的另一件事。

如果第一个索引是A desc, B asc和第二个A asc, B asc, C asc,那么删除第一个索引并不是真正的方法,因为第二个索引不是第一个索引的超集,如果排序是在第一个索引中写的,那么你的查询就无法从第二个索引中受益。

在某些情况下,例如当您使用第一个索引时,您可以order by A desc, B asc(当然)和A asc, B desc,但您也可以创建一个将使用该索引的任何部分的查询,例如{ {1}}。

但是Order by A desc这样的查询不会被第一个索引“覆盖”。

所以我想加起来,你通常可以删除第一个索引,但这取决于你的表配置和你的查询(当然还有索引)。

答案 4 :(得分:2)

我通常会在表中找到包含历史数据的“几乎”相似的索引。如果column C是日期或整数列,请小心。它很可能用于满足WHERE tblA.C = MAX(tblB.C)中的MAX函数,它完全跳过表并使用仅索引访问路径。

相关问题