Mysql 多列索引与多索引/索引合并

Mysql 多列索引与多索引/索引合并,mysql,database,optimization,Mysql,Database,Optimization,假设我们有一个包含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) Idx

假设我们有一个包含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个列,它们将以不同的方式和组合连接起来。是否最好为这些组合创建多个列索引?或者只需找到最常用的最小的多列集合,在这些列上建立多列索引,然后为其余的列创建单独的索引?

在(a,B,C)上的复合索引将涵盖这3个查询,因此您不需要在(a)和(a,B)上建立索引。它也比索引合并快

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

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

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

我不明白你的最后一点。读取850行(稍微但仍然)比读取1000行要好。当您必须读取超过50%的结果时,表扫描比索引扫描更好,因为对于索引中的每一行,您也必须读取表中的行。除了覆盖索引外,如果C将使您的索引覆盖一个(它将包含查询检索到的所有列),请使用ITI。如果您的意思是,在这种情况下,索引
(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,则需要单独的索引