【问题标题】:Mysql - LEFT JOIN way faster than INNER JOINMysql - LEFT JOIN 比 INNER JOIN 快
【发布时间】:2018-07-10 12:00:33
【问题描述】:

我有两张桌子

表 X:数百万或记录

|-----|-----|-----|-----|
|  a  |  b  |  c  |  d  |
|-----|-----|-----|-----|

表 Y:只有几条记录

|-----|-----|
|  e  |  f  |
|-----|-----|

X.d 允许我在X.d = Y.e 上加入两个表

我有以下指标:

  • (X.a)
  • (X.b)
  • (X.c)
  • (X.d)
  • (X.a、X.b、X.c、X.d)
  • (是)

我们的一个应用程序正在执行以下查询,该查询需要很长时间才能运行:

SELECT * 
FROM X
INNER JOIN Y ON X.d = Y.e
WHERE 
      X.a in (1, 2, 3)
  AND X.b IS NULL
  AND X.c in (4, 5 ,6)
  AND X.d in (7, 8, 9)

INNER JOIN改成LEFT JOIN后,查询速度极快:

SELECT * 
FROM X
LEFT JOIN Y ON X.d = Y.e
WHERE 
      X.a in (1, 2, 3)
      AND X.b IS NULL
      AND X.c in (4, 5 ,6)
      AND X.d in (7, 8, 9)

查看这些查询的解释计划,第一个查询正在执行 full scan,而第二个查询仅在我的复合索引上执行 Index Scan (range)。 我在 SO 上看到过其他帖子,但他们有不同的场景。

为什么计划如此不同?

【问题讨论】:

  • 我不知道原因,但你可以尝试用USE KEYFORCE KEY“修复”它。
  • 请为每个查询提供EXPLAIN SELECT ...

标签: mysql performance left-join inner-join mariadb


【解决方案1】:

LEFT JOIN 并不比 INNER JOIN 快。它始终取决于表的结构,而适当的键索引是否应用于该表。如果您不使用依赖项或索引,毫无疑问,Left Join 会更快,因为那不是扫描完成表。但是如果场景发生变化并且两个表都依赖于适当的集群索引,那么两个 Join 都尽可能提供可行的数据。

Left Join 如果您不使用正确的任何表索引,总是更快。有时它也取决于数据和数据结构,因为每个场景都有自己的足够逻辑。

Post INNER JOIN vs LEFT JOIN 例如,这与 MsSQL 相关,但适用于 MySql 和 MsSql。

【讨论】:

  • 我有一个匹配的索引,但只有左连接从中获利
  • 那么这两个查询都为您提供了相同的结果,还是您面临任何问题?
  • 它们提供相同的结果集,但计划不同,执行时间差异很大
  • 时差很大,因为你有 n 依赖的操作数。
  • 或者您可以通过explain关键字查看您的查询详情,然后在mysql中查询。
【解决方案2】:

不同计划的原因是 LEFT JOIN 将强制表的连接顺序与它们在查询中出现的顺序相匹配。如果没有左连接,优化器将为您选择连接顺序,在这种情况下,它会首先选择非常小的表。 (您可以通过查看表的列出顺序在explain 中看到这一点。)切换连接顺序后,X 的索引将更改为 KEY d,它的数据集必须比复合键大得多。

要解决此问题,请将您的选择更改为 SELECT STRAIGHT_JOIN *。这比USE INDEX 更受欢迎,这样优化器仍然可以为表 X 选择最佳键...您可能会找到比 a、b、c、d 更好的复合键,或者如果 X 中的数据发生显着变化,则可以选择以下之一你的其他键可能会更好。

我必须指出,您通常不能只切换到 LEFT JOIN。返回的数据通常会有所不同!

【讨论】:

  • 谢谢。在我的情况下,结果集是相同的
【解决方案3】:

删除INDEX(a),因为您的复合索引是多余的

INDEX(b) 替换为INDEX(b,d)

然后提供EXPLAIN SELECT ...,以便我们进一步讨论。

【讨论】:

    猜你喜欢
    • 2013-02-07
    • 2010-12-21
    • 2015-03-03
    • 2012-09-10
    • 2015-11-29
    • 1970-01-01
    • 2016-12-14
    • 2019-10-09
    • 1970-01-01
    相关资源
    最近更新 更多