我现在正在维护别人的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
由于
答案 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内部优化器会对此进行排序。