是否应该删除 MySQL 中的 "duplicate" 个索引?

Should "duplicate" indices in MySQL be deleted?

我知道在 MySQL 中 (A,B,C) 的索引有利于 ANDed WHERE 子句与 |A|、|A、B|、|A、B、C|。这使得看起来拥有索引 (A,B,C) 意味着在 (A) 上使用单个索引或在 (A,B) 上使用复合索引没有意义。

1.这是真的吗?

2。当您已经在 (A,B,C) 上建立索引时,在 (A) 上维护索引只是一种浪费吗?

  1. 几乎总是

有一种非常罕见的情况,如果:

  • A作为独立索引使用频率最高,
  • 使用 A,BA,B,C 的查询非常罕见,并且
  • sizeof(A) 明显小于 sizeof(A,B,C),并且
  • 您的内存受限,因此通常索引 A,B,C 使用大量缓冲池 size/key 缓存大小以阻止其他查询;

那么可能会有一个 可能 小的好处,它有一个索引的小重复子集 A

注意:可能包括其他条件

我相信你们两个问题的答案是一样的:几乎完全正确;在 (A, B, C) 和 (A) 上都有索引几乎总是很浪费。

作为 Danblack ,大小可能会有细微差别,尽管这可能可以忽略不计。

更重要的是,根据我的经验,请注意 (A) 实际上是 (A, Primary),其中 Primary 是那些尚未显式包含在索引中的主键列。实际上,这通常意味着 (A, Id)。那么,另一个索引实际上是 (A, B, C, Id)。请注意这如何影响在索引中遇到行的顺序。

想象一下这样做:

SELECT *
FROM MyTable
WHERE A = 'Whatever'
ORDER BY Id

Index (A),又名 (A, Id),非常适合这个。对于 A 的任何固定值,相应的行然后按 Id 排序。无需排序 - 结果符合我们的要求。

但是,对于索引 (A, B, C),AKA (A, B, C, Id),它是不同的。对于 A 的任何固定值,相应的行然后由 B 排序!这意味着上述查询将需要对结果进行排序。

EXPLAIN 应该证实我所描述的内容。如果只有 (A, B, C) 索引可用,则 filesort 将发生,但如果 (A) 可用则不会。

很容易看出,如果 A 的特定值通常只有很少的行,那么这无关紧要。但是,如果这样的值可能有 100,000 行,那么 filesort开始有影响。在这种情况下,您可能会选择索引 (A) 来针对这种情况进行优化。

一般来说,这样的前缀索引是多余的。不过,最好分析您的索引和查询以识别这些场景。在极少数情况下,可能值得添加一个。在更常见的情况下,至少您可以将这些影响权衡到您的整体索引选择中。