我发现在某些情况下会有像
这样的查询select
usertable.userid,
(select top 1 name from nametable where userid = usertable.userid) as name
from usertable
where active = 1
在SS2008R2中,比等效连接查询
要长一个数量级select
usertable.userid,
nametable.name
from usertable
left join nametable on nametable.userid = usertable.userid
where usertable.active = 1
其中两个表都已编入索引并且行数超过100k。有趣的是,在原始查询中插入一个top子句使其与连接查询相同:
select
top (select count(*) from usertable where active = 1) usertable.userid,
(select top 1 name from nametable where userid = usertable.userid) as name
from usertable
where active = 1
有没有人知道为什么原始查询的表现如此糟糕?
答案 0 :(得分:3)
嗯,查询是不同的 - 除非userid
列是主键或具有唯一性约束,否则第二个查询可能会返回比第一个更多的行。
也就是说,假设userid是主键/唯一尝试删除第一个子查询的TOP 1
部分:
select
usertable.userid,
(select name from nametable where userid = usertable.userid) as name
from usertable
where active = 1
答案 1 :(得分:2)
这是一个相关的子查询,这意味着它需要在外部查询的每个返回行执行一次,因为它引用了外部查询中的一个字段。
JOIN
为整个结果集运行一次并合并。您的子查询运行外部查询,然后对于每个返回的行,它再次运行子查询。
答案 2 :(得分:1)
原始查询将执行子select
次数与行数相同,因此性能较差。
当您JOIN
时,您立即获得整个结果集。