[英]How to use forceseek scan in SQL Server
I am using SQL Server 2012. 我正在使用SQL Server 2012。
My queries are: 我的查询是:
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
I have included the execution plans of them. 我已经包括了他们的执行计划。
I am not able to differentiate between the 2 queries, and they produce the same execution plan. 我无法区分这两个查询,它们产生相同的执行计划。
There is no difference between the two plans because SQL Server has already chosen to do an Index Seek on tab2.IX_nm2
without the need for the FORCESEEK
hint. 两种计划之间没有区别,因为SQL Server已经选择在tab2.IX_nm2
上执行索引查找,而无需FORCESEEK
提示。
Take a look at the plan produced: 看一下生成的计划:
You want all rows from tab
, so SQL Server does a table scan. 您需要tab
所有行,因此SQL Server进行表扫描。 It won't use IX_nm
because it doesn't contain nm
and would have to do a lookup to retrieve this column from the heap. 它不会使用IX_nm
因为它不包含nm
,并且必须进行查找以从堆中检索此列。 However, you could use a CLUSTERED
index which will remove that table scan: 但是,您可以使用CLUSTERED
索引来删除该表扫描:
create CLUSTERED index IX_nm on tab(id);
The Nested Loop between The Scan and the Seek basically says, For every row returned by the Table Scan on tab, get me the corresponding row from tab2 based on the ID
. “扫描”和“查找”之间的嵌套循环基本上说: For every row returned by the Table Scan on tab, get me the corresponding row from tab2 based on the ID
。 The underlying statistics on IX_nm2
indicates to SQL Server that there is likely to be only one or two rows returned and so it does a Seek for those rows, rather than scans the whole table. IX_nm2
上的基础统计信息向SQL Server指示可能仅返回一或两行,因此它对这些行执行“查找”,而不是扫描整个表。
However, because your index is NONCLUSTERED
and doesn't include age
, SQL Server also has to do a RID Lookup to get the age
. 但是,由于索引是NONCLUSTERED
且不包含age
,因此SQL Server还必须执行RID查找来获取age
。 Again, you can avoid this by making the index IX_nm2
a CLUSTERED
index. 同样,可以通过将索引IX_nm2
为CLUSTERED
索引来避免这种情况。
CREATE clustered index CIX_nm2 on tab2(id1);
This would result in a much simpler plan. 这将导致更简单的计划。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.