4

我有多个连接,包括 mysql 中的左连接。有两种方法可以做到这一点。

  1. 我可以在每次加入后立即设置“ON”条件:

    select * from A join B ON(A.bid=B.ID) join C ON(B.cid=C.ID) join D ON(c.did=D.ID)

  2. 我可以将它们全部放在一个“ON”子句中:

    select * from A join B join C join D ON(A.bid=B.ID AND B.cid=C.ID AND c.did=D.ID)

哪种方式更好?

如果我在查询中需要左连接右连接,有什么不同吗?

4

2 回答 2

6

对于简单的用途,MySQL 几乎不可避免地会以相同的方式执行它们,因此这是一种偏好和可读性的方式(这是一个很大的争论主题)。

然而,对于更复杂的查询,特别OUTER JOIN是具有可能成为磁盘和 io 绑定的 s 的聚合查询 - 不使用带有 OUTER JOIN 查询的 WHERE 子句可能会产生性能和不可见的影响。

运行 8 分钟或 0.8 秒的查询之间的差异最终可能取决于WHERE子句,特别是当它与索引有关时(MySQL 如何使用索引):WHERE子句是为查询优化器提供所需信息的核心部分完成它的工作并告诉引擎如何以最有效的方式执行查询。

MySQL 如何使用 WHERE 优化查询

“本节讨论可用于处理 WHERE 子句的优化......通过尝试所有可能性来找到用于连接表的最佳连接组合。如果 ORDER BY 和 GROUP BY 子句中的所有列都来自同一个表,则该表是加入时优先考虑。”

对于连接中的每个表,构造一个更简单的 WHERE 以获得对表的快速 WHERE 评估并尽快跳过行

一些例子:

全表扫描(类型 = ALL),Using where在 EXTRA中没有

[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id AND cr.role = cr2.role AND cr.util = 1000

[Err] Out of memory

用于where优化结果,带有索引 ( Using where, Using index)

[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id 
WHERE cr.role = cr2.role 
AND cr.util = 1000

515661 rows in set (0.124s)

**** ON/WHERE 的组合 - 相同的结果 - ******** 中的相同EXPLAIN计划

[SQL] SELECT cr.id,cr2.role FROM CReportsAL cr
LEFT JOIN CReportsCA cr2
ON cr.id = cr2.id 
AND cr.role = cr2.role
WHERE cr.util = 1000

515661 rows in set (0.121s)

MySQL 通常足够聪明,可以计算出像上面这样的简单查询,并且会以类似的方式执行它们,但在某些情况下它不会。

外连接查询性能:

由于 LEFT JOIN 和 RIGHT JOIN 都是 OUTER JOIN(此处进行了深入的回顾),因此出现了笛卡尔积的问题,必须避免表扫描,以便尽可能快地消除查询不需要的行尽可能。

WHERE, 索引和查询优化器一起使用可以完全消除笛卡尔积所带来的问题,当仔细使用聚合函数,如,,AVERAGE等等。通过用户适当的索引和 WHERE 的使用,运行时间减少了几个数量级。条款。GROUP BYSUMDISTINCT

最后

同样,对于大多数查询,查询优化器将以相同的方式执行这些 - 使其成为一种首选方式,但是当查询优化变得重要时,WHERE它是一个非常重要的工具。通过将索引 col 指定为附加的 ON..AND ON 子句,我在某些情况下看到了一些性能提升,INNER JOIN但我无法告诉您原因。

于 2013-08-11T05:39:00.320 回答
3

Put the ON clause with the JOIN it applies to.

The reasons are:

  • readability: others can easily see how the tables are joined
  • performance: if you leave the conditions later in the query, you'll get way more joins happening than need to - it's like putting the conditions in the where clause
  • convention: by following normal style, your code will be more portable and less likely to encounter problems that may occur with unusual syntax - do what works
于 2013-08-11T06:47:52.090 回答