【问题标题】:Should I create 2 indexes for the same column to speed up a join?我应该为同一列创建 2 个索引以加快连接速度吗?
【发布时间】:2021-04-29 10:18:24
【问题描述】:

我是数据库索引的新手,我刚刚了解了索引是什么、聚簇和非聚簇之间的区别以及复合索引是什么。

所以对于像这样的内连接查询:

SELECT columnA
FROM table1
INNER JOIN table2
ON table1.columnA= table2.columnA;

为了加快join的速度,我应该创建2个索引,一个为table1.columnA,另一个为table2.columnA,还是只为table1table2创建1个索引?

一个就够了?我不明白,例如,如果我先从table2 中选择一些数据,然后根据结果加入columnA,然后我会从table2 中逐一遍历结果,然后从table2.columnA 在这里完全没用,因为我现在不需要在 table2 中找到任何东西。所以我需要table1.columnA 的索引。

反之亦然,如果我先从table1 中选择一些结果并想加入columnA,我需要table2.columnA

好吧,我不知道实际上“先选择 xxxx,然后根据...加入”看起来如何,但我脑海中浮现出这种情况。如果有人也可以举一个简单的例子,将不胜感激。

【问题讨论】:

  • 通常一个表上的索引就足够了,但您可能会发现两个索引更好。测试您的数据,看看什么效果最好。
  • @GordonLinoff 让我添加更多细节。
  • 在这里考虑哪个表可以为嵌套循环提供更好的驱动表:如果它以 Table1 开头,它将获得少量行,这将在 Table2 中返回比读取所有行少得多的行表2第一?是否会因为任一表中的每一行在另一表中都有匹配的行而大致相同? MySQL 可以进行哈希连接(最后),因此嵌套循环可能不是最好的主意,但列上的索引可以为数据库提供更少量的数据来读取(只是整个索引而不是整个表)。您的实际查询也可以重写为使用intersect
  • @AndrewSayer MySQL 不支持insersect 关键字或操作。

标签: mysql sql join indexing query-optimization


【解决方案1】:

一个索引就足够了,但问题是哪一个?

这取决于 MySQL 优化器如何决定对连接中的表进行排序。

对于内部连接,table1 INNER JOIN table2table2 INNER JOIN table1 的结果相同,因此优化器可能会选择更改顺序。按照您在查询中指定的顺序连接表不受限制。

从索引的角度来看,区别在于它是先遍历 table1 的行,然后查找 table2 中的匹配行,反之亦然:遍历 table2 的行,然后查找 table1 中的行。

MySQL 将连接作为“嵌套循环”。就好像你用你最喜欢的语言编写了这样的代码:

foreach row in table1 {
  look up rows in table2 matching table1.column_name
}

此查找将使用 table2 中的索引。 table1 中的索引与此示例无关,因为您的查询无论如何都在扫描 table1 的每一行。

你怎么知道使用了哪个表顺序?您可以使用EXPLAIN。它将为查询中的每个表引用显示一行,并以连接顺序显示它们。

请记住,任一表中存在索引可能会影响优化器对表排序方式的选择。它将尝试选择导致查询成本最低的表顺序。

因此,您将索引添加到哪个表可能并不重要,因为无论您将索引放在哪个表上,都将成为连接顺序中的第二个表,因为这样可以更有效地进行查找。使用 EXPLAIN 找出答案。

【讨论】:

  • 令人难以置信的精彩解释!你的回答正是我在想的!我想确定一件事:所以对于inner join,无论我将columnA 索引放在哪个表上,我都做对了吗?
  • 使用EXPLAIN 检查优化器的作用。这应该是您从这次讨论中得到的收获。
【解决方案2】:

在设计合理的关系数据库中,90% 的情况下,连接在一起的两列之一是主键,因此应该为其构建聚集索引。

因此,只要您处于这种情况下,您就不需要做任何事情。添加其他非聚集索引的唯一原因是,如果您还在语句末尾使用 where 子句进一步过滤连接,则需要确保连接列和过滤列都在正确的一起索引(即正确的排序顺序等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2023-01-05
    • 2012-01-31
    相关资源
    最近更新 更多