在下面的示例中,结果Index Spool
已经排序,为什么我们在Top N Sort
这里而不是 simple Top
?
use tempdb;
go
create table dbo.t1 (id int identity primary key, v int);
create table dbo.t2 (id int identity primary key, v int);
insert into dbo.t1
(v)
select top (1000)
row_number() over (order by 1/0)
from
master.dbo.spt_values a cross join
master.dbo.spt_values b;
insert into dbo.t2
(v)
select top (10000)
row_number() over (order by 1/0) + 10000
from
master.dbo.spt_values a cross join
master.dbo.spt_values b;
set statistics xml, io on;
select
sum(a.v + b.v)
from
dbo.t1 a outer apply
(select top (1) v from dbo.t2 where v >= a.v order by v) b;
set statistics xml,io off;
go
drop table dbo.t1, dbo.t2;
go
它在所有版本中都可以重现2008 R2
(我只是没有要测试的早期版本的服务器)
这是当前优化器的一个有点烦人的限制。
作为The Eager Index Spool 和 The Optimizer 的一部分,我写了一点:
因为您订购
[v]
,而您的主键打开[id]
。顺便说一句:当您使用
SUM(a.v) + ISNULL(SUM(b.v), NULL)
而不是sum(a.v + b.v)
.另一方面,在这种情况下,结果可能会有所不同,因为您使用 OUTER APPLY(类似于 LEFT JOIN),所以当没有找到 "table" 的记录时
[b]
,它也会忽略a.v
原始查询中的(因为a.v + NULL
是NULL
)虽然a.v
它会在我建议的版本的总和中(这是您的数据,所以您必须决定,如果您继续使用sum(a.v + b.v)
它,这将是一个很好的评论目标,即这是预期的行为: -)。