12

拥有多年的 DBA 经验,我相信我知道问题的答案,但我认为检查我的基础永远不会有坏处。

使用 SQL Server,假设我有一个表,它在 columnA和 column上有一个索引B,在 columns AB和上有一个第二个索引C,删除第一个索引是否安全,因为第二个索引基本上会满足将从中受益的查询第一个索引?

4

5 回答 5

30

这取决于,但答案通常是“是的,您可以将索引放在 (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) 更有效) 索引,因为您可以获得 (A,B) 索引的每页读取的更多信息。因此,即使 (A,B) 是多余的,它也可能值得保留。您还需要考虑表格的波动性;如果表很少更改,则额外的索引无关紧要;如果表变化很大,额外的索引会减慢对表的修改。这是否重要很难猜测。您可能需要进行性能测量。

于 2012-12-09T20:17:37.760 回答
11

第一个索引涵盖在 上查找的查询,A第二A,B个索引可用于涵盖在 上查找的查询AA,B或者A,B,C显然是第一种情况的超集。

IfC非常宽,但是索引A,B可能仍然有用,因为它可以用更少的读取来满足某些查询。

例如,如果C是一char(800)列,则以下查询可能会因提供更窄的索引而受益匪浅。

SELECT a,b
FROM YourTable
ORDER BY a,b
于 2012-12-09T20:16:28.577 回答
7

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

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

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

于 2012-12-09T20:17:09.677 回答
4

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

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

在某些情况下,例如当您使用第一个索引时,您可以order by A desc, B asc(当然) and A asc, B desc,但您也可以进行查询以使用该索引的任何部分,例如Order by A desc.

但是像order by A asc, B asc, 这样的查询不会被第一个索引“覆盖”。

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

于 2012-12-28T07:55:37.277 回答
2

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

于 2012-12-28T20:26:24.727 回答