为什么在这个例子中我们有 Top N Sort?

sep*_*pic 6 sql-server optimization execution-plan

在下面的例子中,结果Index Spool已经排序,为什么我们Top N Sort这里有而不是简单的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
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

它可以在所有版本中重现2008 R2(我只是没有带有早期版本的服务器来测试)

Pau*_*ite 2

这是当前优化器的一个有点烦人的限制。

我在《The Eager Index Spool and The Optimizer》中写了一些关于这一点的文章:

索引假脱机不会告诉优化器它们支持按假脱机索引键排序的输出。如果需要对假脱机的输出进行排序,您可能会看到不必要的排序运算符。无论如何,急切的索引线轴通常应该被永久索引所取代,所以这在很多时候都是一个小问题。