问题 使用JOIN而不是WHERE进行过滤


在SQL(MSSQL,Oracle等等)中,在连接表时,将过滤器添加到JOIN语句而不是在WHERE子句中有什么好处?

SELECT * FROM X INNER JOIN Y ON X.A = Y.A WHERE X.B = 'SOMETHING'

SELECT * FROM X INNER JOIN Y ON X.A = Y.A AND X.B = 'SOMETHING'

我意识到这并不适用于所有情况,但我注意到在某些情况下,通过将过滤条件放在JOIN语句中似乎可以获得性能提升。但是,因为它是JOIN语句的一部分,所以它也会使它表现得有些奇怪。

思考?


1028
2017-12-15 13:08


起源

重复: stackoverflow.com/questions/1018952/... - Tom H


答案:


对于 INNER JOIN 查询,这些过滤器的性能特征将取决于许多因素 - 表的大小,索引,查询的选择性以及特定于执行查询的RDBMS的其他因素。

LEFT 和 RIGHT OUTER JOIN,过滤器的位置比重要 INNER JOIN,因为影响是否会在之前应用(JOIN 条款)或之后(WHERE 条款)进行连接。


5
2017-12-15 13:18



换句话说,在OUTER JOIN的ON子句中包含过滤器可能(将)通过将其包含在WHERE子句中而产生不同的结果。 - APC
包括一个相等的过滤器 WHERE 的条款 OUTER JOIN 有效地使它成为一个 INNER JOIN。 - Quassnoi


我有时会在具有大量连接的查询中执行此操作,因为它在查询的一部分中将所有有关连接的信息本地化,而不是在连接条件中有一些,而在where子句中有一些。


5
2017-12-15 13:11



这也是我如何使用它:从选择中分离modell(join)(其中) - lexu


对于INNER JOIN,我不希望出现性能差异,而是使用相同的计划,无论过滤器是在JOIN ... ON子句还是WHERE子句中。我个人更喜欢使用JOIN子句中的连接条件和WHERE子句中的过滤 - 一种将所有“参数”粘贴到同一位置的SQL语句的方法 - 这不一定是明智的或者不是 - 深思熟虑。相反,有些人喜欢在JOIN子句中使用所有内容来保持所有内容。

外连接的情况不同 - “a.a_id = b.a_id和b.type = 1上的左外连接”和“a.a_id = b.a_id上的左外连接b”之间存在显着差异WHERE b.type = 1“ - 实际上后者隐式强制内连接。这是将所有这些条件置于JOIN子句中的另一个原因,以保持一致性。


3
2017-12-15 13:19





这些语法是同义词,并且大多数都针对相同的事情进行了优化 RDBMS

我通常更喜欢这种语法:

SELECT  *
FROM    X
INNER JOIN
        Y
ON      X.A = Y.A
WHERE   X.B = 'SOMETHING'

什么时候 B 不是两者之间逻辑联系的一部分 A 和 B, 和这个:

SELECT  *
FROM    X
INNER JOIN
        Y
ON      X.A = Y.A
        AND X.B = 'SOMETHING'

几时。


2
2017-12-15 13:22





没有,除了清晰和意义。除非你有外连接。


0
2017-12-15 13:22





作为一个人(而不是一个优化器)自己,在维护查询时,我会寻找一个连接条件 JOIN 条款和搜索条件 WHERE 条款。

当然,您需要在性能问题和代码维护问题之间取得平衡。但是,我的首要任务是在第一个实例中使用良好的逻辑代码,然后根据需要进


0
2017-12-16 13:49