[鐵人賽][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三種方法(新增兩種方法)
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'
可以看到上下的作業不同,使用索引也不同。
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'
可以看到上下的作業不同,使用索引也不同。
結論:如果查詢陳述句選擇性很高,透過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'
上面操作使用叢集索引搜尋,但下面卻使用索引掃描。
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'
結論:何時該用forcescan呢?當你已經知道該查詢使用full table or index scan 就足夠時,
你可能會使用該hint,以便取代查詢優化程式所選擇的執行計畫操作(可能是index seek),雖然機會可能不大。