![](/img/trans.png)
[英]Get SQL Server to use index seek + key lookup instead of clustered index scan, without WITH (FORCESEEK)
[英]How to use forceseek scan in SQL Server
我正在使用SQL Server 2012。
我的查询是:
create table tab (id int, nm varchar(10))
insert into tab values (1, 'a'), (2, 'b'), (3, 'c')
create index IX_nm on tab(id)
go
create table tab2(id1 int, age int)
insert into tab2 values (1, 21), (2, 22), (3, 54)
create index IX_nm2 on tab2(id1)
go
select *
from tab a
inner join tab2 b on a.id = b.id1
select *
from tab a
inner join tab2 b with(forceseek) on a.id = b.id1
我已经包括了他们的执行计划。
我无法区分这两个查询,它们产生相同的执行计划。
两种计划之间没有区别,因为SQL Server已经选择在tab2.IX_nm2
上执行索引查找,而无需FORCESEEK
提示。
看一下生成的计划:
您需要tab
所有行,因此SQL Server进行表扫描。 它不会使用IX_nm
因为它不包含nm
,并且必须进行查找以从堆中检索此列。 但是,您可以使用CLUSTERED
索引来删除该表扫描:
create CLUSTERED index IX_nm on tab(id);
“扫描”和“查找”之间的嵌套循环基本上说: For every row returned by the Table Scan on tab, get me the corresponding row from tab2 based on the ID
。 IX_nm2
上的基础统计信息向SQL Server指示可能仅返回一或两行,因此它对这些行执行“查找”,而不是扫描整个表。
但是,由于索引是NONCLUSTERED
且不包含age
,因此SQL Server还必须执行RID查找来获取age
。 同样,可以通过将索引IX_nm2
为CLUSTERED
索引来避免这种情况。
CREATE clustered index CIX_nm2 on tab2(id1);
这将导致更简单的计划。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.