在JOIN子句和WHERE子句中放置条件之间有什么区别(性能、最佳实践等)吗?

例如……

-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'

-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'

你更喜欢哪一个(也许为什么)?


当前回答

WHERE将在JOIN发生后进行筛选。

在JOIN上的过滤器,以防止在JOIN过程中添加行。

其他回答

在筛选连接时,我通常看到性能有所提高。特别是如果可以联接两个表的索引列。大多数查询都这样做,您应该能够减少逻辑读取,在大容量环境中,这是一个比执行时间更好的性能指标。

当有人展示他们的SQL基准测试时,他们在午夜在开发服务器上执行了一个sproc的两个版本5万次,并比较了平均时间,我总是觉得有点好笑。

WHERE将在JOIN发生后进行筛选。

在JOIN上的过滤器,以防止在JOIN过程中添加行。

关系代数允许WHERE子句和INNER JOIN中的谓词互换性,因此即使是带有WHERE子句的INNER JOIN查询也可以由优化器重新安排谓词,以便在JOIN过程中已经排除谓词。

我建议您以最易读的方式编写查询。

有时,这包括使INNER JOIN相对“不完整”,并将一些标准放在WHERE中,只是为了使过滤条件列表更容易维护。

例如,不要:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

写:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

当然,这要视情况而定。

同意第二多数投票的答案,使用LEFT JOIN或RIGHT JOIN会有很大的不同。实际上,下面两种说法是等价的。你可以看到AND子句在JOIN之前进行筛选而WHERE子句在JOIN之后进行筛选。

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND ORD.OrderDate >'20090515'

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN (SELECT * FROM dbo.Orders WHERE OrderDate >'20090515') AS ORD 
ON CUS.CustomerID = ORD.CustomerID

我更喜欢使用JOIN来连接完整的表/视图,然后使用WHERE来引入结果集的谓词。

它在语法上感觉更简洁。