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是这样。