这两个SQL语句之间是否存在任何性能或功能差异?

时间:2013-07-23 10:35:49

标签: sql sql-server

我现在正在维护别人的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

由于

5 个答案:

答案 0 :(得分:3)

使用inner join这不会产生太大的影响,因为SQL有一个查询优化器,它会尽最大努力以最有效的方式排除查询(不完美)。

如果这是一个outer join,它可以有所作为,但它需要注意的事情

答案 1 :(得分:3)

两个查询的表现都是一样的。内连接没有区别。

答案 2 :(得分: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岁(或年龄较大)的行。

答案 3 :(得分:2)

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

您应该担心代码的可读性和维护,如果它太早或者几乎没有可能的优化。

这应该是加入条件还是过滤器?从查看代码本身开始,我认为它是过滤器的一部分。

答案 4 :(得分:1)

这取决于您使用的是哪个数据库。通常,DB内部优化器会对此进行排序。

请在这里查看:INNER JOIN ON vs WHERE clause