【问题标题】:Multiple Column Index vs Multiple Indexes/Index Merge多列索引与多索引/索引合并
【发布时间】:2013-02-21 07:37:21
【问题描述】:

假设我们有一个包含 4 列的表:A、B、C 和 D

假设我们有一些查询将加入或针对这些列执行子句:

Q1: Where A = ?
Q2: Where A = ?, B = ?
Q3: Where A = ?, B = ?, C = ?

既然我们知道我们将在三个不同的上下文中使用这些列,那么最好创建三个不同的索引吗?还是三个不同的多重索引?

索引合并:

Idx1: Create index A_idx ON table (A)
Idx2: Create index B_idx ON table (B)
Idx3: Create index C_idx ON table (C)

多重索引

Idx1: Create index A_idx ON table(A)
Idx2: Create index AB_idx ON table(A,B)
Idx3: Create index ABC_idx ON table(A,B,C)

这是一个简化的案例。假设我们有 10-15 列,它们将以不同的方式和组合被连接或放置。是否最好为他们将收到的这些组合创建多个列索引?或者只是找到最常用的多列的最小集合,在这些列上构建多列索引,然后为其余的创建单独的索引?

【问题讨论】:

    标签: mysql database optimization


    【解决方案1】:

    (A,B,C) 上的复合索引将涵盖 3 个查询,因此您不需要 (A) 和 ON (A,B) 上的索引。它也比 index_merge 更快。

    拥有多个索引的唯一原因是某些查询不会被索引覆盖(例如,它们包括 B 和 C,但不包括 A)

    还请记住,列的最重要特征之一,即决定是否应将其包含在索引中,不是它是否用于查询,而是基数。如果对该列的查询不会排除很多行,则不应将其包含在索引中。

    假设你有 A,B,C 对于给定的 A 值,您有 20% 的行。从这些行中,对于给定的 B 值,您有 1% 的行。假设这些条件 (A,B) 从表中过滤 1000 行。应用 C 后,您会收到 850 行。 C 上的索引无效,并且 (A,B) 是此查询的最佳索引

    【讨论】:

    • 我不明白你的最后一点。读取 850 行(稍微但仍然)比读取 1000 行好。
    • 当您必须读取超过 50% 的结果时,表扫描比索引扫描更好,因为对于索引中的每一行,您还必须读取表中的行。除了覆盖索引,如果 C 会让你的索引覆盖一个(它将包含查询检索到的所有列),使用它
    • 如果你的意思是在这种情况下索引(A,B) 比索引(C) 好,我同意。但是(A,B,C) 会更好。
    • 因此,即使我的许多查询只会引用 A,但其他一些查询可能会引用 B、C,创建多列索引 (A、B、C) 也不是问题?我明白你所说的关于在具有高基数的列上省略索引的说法。但回到要点——如果我创建一个索引 A、B、C——在我只想要 A、只想要 B 或只想要 C 的情况下使用它就足够了?并且仍然涵盖 A&B、B&C、C&A 的案例。如果这变成说,10 列经常在子句中使用,但很少复合使用。
    • (A,B,C) 可用于引用 A、A 和 B 或 A、B 和 C 的查询。它不能用于引用 B 和 C 的查询,但不能A 如果只需要 B 或只需要 C,则需要单独的索引
    猜你喜欢
    • 2021-09-01
    • 2011-11-07
    • 2010-09-15
    • 2018-07-27
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2020-05-06
    相关资源
    最近更新 更多