SQL server连接与子查询性能问题

SQL server连接与子查询性能问题,sql,sql-server,join,subquery,Sql,Sql Server,Join,Subquery,我发现在某些情况下 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

我发现在某些情况下

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行。有趣的是,将顶部子句插入到原始查询中,使其与连接查询一致:

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

有人知道为什么原始查询执行得如此糟糕吗?

它是一个相关子查询,这意味着它需要在外部查询的每个返回行执行一次,因为它引用了外部查询中的一个字段


JOIN
对整个结果集运行一次并合并。您的子查询将运行外部查询,然后对于返回的每一行,它将再次运行子查询。

原始查询将执行子查询
select
的次数与行数相同,因此性能较差


当您
JOIN
时,您会立即得到整个结果集。

好吧,查询是不同的-除非
userid
列是主键或具有唯一性约束,否则第二个查询可能返回比第一个查询更多的行

也就是说,假设userid是主键/唯一键,请尝试删除第一个子查询的
TOP 1
部分:

select 
   usertable.userid,
   (select name from nametable where userid = usertable.userid) as name 
from usertable 
where active = 1

仅供参考,在诊断性能问题时,您应该始终获得查询执行计划。如果您可以访问Safari联机丛书,请参阅“Microsoft®SQL Server 2005内部:查询优化和优化-第3章”或另一个完全成功的链接。我把它放在那里是为了避免运行时错误,因为查询是动态生成的。现在我需要弄清楚是否可以安全地将其作为一般规则删除。我不认为SQL Server是这样。