在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语句的一部分,所以它也会使它表现得有些奇怪。
思考?
对于 INNER JOIN
查询,这些过滤器的性能特征将取决于许多因素 - 表的大小,索引,查询的选择性以及特定于执行查询的RDBMS的其他因素。
在 LEFT
和 RIGHT OUTER JOIN
,过滤器的位置比重要 INNER JOIN
,因为影响是否会在之前应用(JOIN
条款)或之后(WHERE
条款)进行连接。
我有时会在具有大量连接的查询中执行此操作,因为它在查询的一部分中将所有有关连接的信息本地化,而不是在连接条件中有一些,而在where子句中有一些。
对于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子句中的另一个原因,以保持一致性。
这些语法是同义词,并且大多数都针对相同的事情进行了优化 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'
几时。
作为一个人(而不是一个优化器)自己,在维护查询时,我会寻找一个连接条件 JOIN
条款和搜索条件 WHERE
条款。
当然,您需要在性能问题和代码维护问题之间取得平衡。但是,我的首要任务是在第一个实例中使用良好的逻辑代码,然后根据需要进