繁体   English   中英

如何在SQL Server中使用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_nm2CLUSTERED索引来避免这种情况。

CREATE clustered index CIX_nm2 on tab2(id1);

这将导致更简单的计划。

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM