[鐵人賽][Denali 新特性探險18]New and Enhanced Query Optimizer Hints

[鐵人賽][Denali 新特性探險18]New and Enhanced Query Optimizer Hints

Denali對於查詢優化加強 FORCESEEK和FORCESCAN hint可用性,

下面我將利用幾個例子讓你了解相關用法和執行計畫作業上的差異。

 

--建立測試資料表和資料
create table MyNum
(
c1 int identity(1,1) not null,
c2 varchar(30),
c3 date
constraint pk_c1 primary key(c1)
)

	
insert into MyNum 
select 'rico1','1982-01-01' union all
select 'rico2','1983-01-01' union all
select 'rico3','2001-01-01' union all
select 'rico4','2003-01-01' union all
select 'rico5','2005-01-01' union all
select 'rico6','2007-01-01' union all
select 'rico7','2010-01-01' union all
select 'rico8','2010-02-01' union all
select 'rico9','2011-01-01' union all
select 'rico10','2010-10-10' 

 

 

 

--建立索引
create nonclustered index nix_1 on MyNum(c2,c3,c1)
create nonclustered index nix_2 on MyNum(c2)
include(c1,c3)

 

 

 

FORCESEEK三種方法(新增兩種方法)

image

1. WITH(FORCESEEK):可參考[SQL SERVER][Performance]善用 FORCESEEK 資料表提示

2. WITH(FORCESEEK)和index hint混合使用:

select * from MyNum
where c1=2 and c2='rico2'
select * from MyNum with(forceseek index(nix_1))
where c1=2 and c2='rico2'

image

可以看到上下的作業不同,使用索引也不同。

 

3. WITH(FORCESEEK)和index hint且指定欄位混合使用:

select * from MyNum
where c1=2 and c2='rico2'
select * from MyNum with(forceseek(nix_2(c2)))
where c1=2 and c2='rico2'

image

可以看到上下的作業不同,使用索引也不同。

 

結論:如果查詢陳述句選擇性很高,透過FORCESEEK可以覆寫查詢最佳化工具所選擇的預設計畫(低成本計畫),

且 Denali 版本中還可以指定相關索引和欄位,可用性可說大大提高。

 

FORCESCAN兩種方法

1.WITH (FORCESCAN)

select * from MyNum 
where c1=2 and c2='rico2'
select * from MyNum with(forcescan)
where c1=2 and c2='rico2'

image

上面操作使用叢集索引搜尋,但下面卻使用索引掃描。

 

2.WITH (FORCESCAN)和index hint混合使用

select * from MyNum 
where c1=2 and c2='rico2'
select * from MyNum with(forcescan index(nix_1))
where c1=2 and c2='rico2'

image

 

結論:何時該用forcescan呢?當你已經知道該查詢使用full table or index scan 就足夠時,

你可能會使用該hint,以便取代查詢優化程式所選擇的執行計畫操作(可能是index seek),雖然機會可能不大。

 

參考 Table Hints (Transact-SQL)