JOIN 子句中的条件是邪恶的 SQL
Posted
技术标签:
【中文标题】JOIN 子句中的条件是邪恶的 SQL【英文标题】:Is condition in the JOIN clause evil SQL 【发布时间】:2013-04-29 04:56:19 【问题描述】:在 JOIN 子句或 WHERE 子句中添加 SQL 条件更好吗? SQL 引擎是否针对这两种方式进行了优化?这取决于引擎吗?
是否总是可以用 WHERE 子句中的条件替换 JOIN 子句中的条件?
这里的例子来说明我对条件的意思
SELECT role_.name
FROM user_role
INNER JOIN user ON user_role.user_id_ = user.id AND
user_role.user_id_ = @user_id
INNER JOIN role ON user_role.role_id = role_.id
对比
SELECT role_.name
FROM user_role
INNER JOIN user ON user_role.user_id_ = user.id
INNER JOIN role ON user_role.role_id = role_.id
WHERE user.id = @user_id
【问题讨论】:
【参考方案1】:如果使用 INNER JOIN,JOIN 子句和 WHERE 条件中的 SQL 条件是等价的。
否则,如果使用任何其他 JOIN(如 LEFT/RIGHT)而不是在基于条件匹配行之后,则会发生另一个步骤,即添加 OUTER ROWS ,即不匹配的行。
WHERE 条件只是过滤掉所有不匹配的行。
See this thread
【讨论】:
假设 op 没有消除 where 子句中的 NULL,那么您对左/右的判断是正确的,这是一个很好的假设,但我喜欢陈述假设。另请注意,mysql 不支持 FULL OUTER JOINS 但 sql-server (op 选择了两个标签) 支持。 这正是我在 google 上搜索的内容,在 JOIN 和 WHERE 中如何处理 NULL 值..感谢您的输入..【参考方案2】:在 join 子句中包含非键条件不仅可以,尤其是在此查询中更可取,因为您可以避免与其他表的某些连接,这些连接进一步连接到 on 子句所属的表。
Where 子句在所有连接都完成后进行评估 - 它是结果集的过滤器。但是通过将条件放在 join 子句中,您可以在它们被 bing 连接时停止被连接的行。
在你的情况下没有区别,因为你没有任何下表,但我经常使用他的技术来提高我的查询性能。
【讨论】:
【参考方案3】:通过查看为这两个查询生成的计划,我们可以看到在 INNER JOIN 或 WHERE 子句中包含条件会生成相同的计划。
但是在 WHERE 子句中使用条件的问题是您将无法处理 OUTER JOINs
【讨论】:
以上是关于JOIN 子句中的条件是邪恶的 SQL的主要内容,如果未能解决你的问题,请参考以下文章
SQL左连接与JOIN条件中的过滤器与WHERE子句中的过滤器[重复]
Spark SQL 中的 where 子句与 join 子句
为啥以及何时在 WHERE 子句中带有条件的 LEFT JOIN 不等于在 ON 中的相同 LEFT JOIN? [复制]