![](/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.