3

我现在正在维护别人的 SQL,我在存储过程中遇到了这个问题:

    SELECT      
    Location.ID, 
    Location.Location, 
    COUNT(Person.ID) As CountAdultMales
FROM        
    Transactions INNER JOIN 
    Location ON Transactions.FKLocationID = Location.ID INNER JOIN  
    Person ON Transactions.FKPersonID = Person.ID 
     AND DATEDIFF(YEAR, Person.DateOfBirth, GETDATE()) >= 18 AND Person.Gender = 1
WHERE
    ((Transactions.Deleted = 0) AND
    (Person.Deleted = 0) AND
    (Location.Deleted = 0))

上面和这个有什么区别吗(我会这样写)

SELECT      
    Location.ID, 
    Location.Location, 
    COUNT(Person.ID) As CountAdultMales
FROM        
    Transactions INNER JOIN 
    Location ON Transactions.FKLocationID = Location.ID INNER JOIN  
    Person ON Transactions.FKPersonID = Person.ID
WHERE
    ((Transactions.Deleted = 0) AND
    (Person.Deleted = 0) AND
    (Location.Deleted = 0) AND
    (DATEDIFF(YEAR, Person.DateOfBirth, GETDATE()) >= 18) AND
    (Person.Gender = 1))

就个人而言,我发现将条件放在 WHERE 子句中最易读,但我想知道是否有性能或其他原因来“条件化”(如果有这样的话)JOIN

谢谢

4

5 回答 5

3

both query's performance is same. There is no difference for inner join.

于 2013-07-23T10:44:45.183 回答
3

由于inner joinSQL 有一个查询优化器,它会尽最大努力以最有效的方式(不完美)执行查询,因此这并不会产生太大的影响。

如果这是一个outer join它可能会有所作为,所以它需要注意

于 2013-07-23T10:41:21.857 回答
2

不要担心这里的执行计划,正如 SO 成员已经说过的,他们应该产生相同的执行计划。问题本身就这么多。

您应该担心代码的可读性和维护是否为时过早或者几乎没有优化可能。

这应该是真正的加入标准还是过滤器?从仅查看代码本身来看,我认为它是过滤器的一部分。

于 2013-07-23T10:55:35.427 回答
2

您的示例中的性能相同,但是您可以通过以下方式对其进行调整:

SELECT      
Location.ID, 
Location.Location, 
COUNT(Person.ID) As CountAdultMales
FROM        
Transactions 
INNER JOIN Location 
ON Transactions.FKLocationID = Location.ID 
INNER JOIN Person 
ON Transactions.FKPersonID = Person.ID 
WHERE
Transactions.Deleted = 0 AND
Person.Deleted = 0 AND
Location.Deleted = 0 AND 
Person.DateOfBirth < dateadd(year, datediff(year, 0, getdate())-17, 0) AND 
Person.Gender = 1

这样,您就不会对所有列进行计算来获得年份。相反,您只需将年份与更快的静态值进行比较。

此查询选择在当年用完之前人们年满 18 岁(或年龄更大)的行。

于 2013-07-23T10:52:16.950 回答
1

这取决于您正在使用哪个数据库。一般来说,数据库内部优化器会解决这个问题。

请看这里:INNER JOIN ON vs WHERE 子句

于 2013-07-23T10:41:40.980 回答