[SQL SERVER][Performance]密度和選擇性
3月份SQL PASS TW活動我有介紹密度和選擇性關係,
統計值透過密度比率來判斷索引欄位選擇性高低,
換句話說,索引有效性取決於統計值,統計值影響執行計畫好壞,
所以統計值在資料庫扮演相當重要的角色。
一般來說低密度索引欄位表示高選擇性(密度越低越適合nonclustered index key),
高選擇性可以幫助查詢優化程式在大資料量中快速搜尋小結果集,
查詢調校過程中,大部分時間會花在索引優化上,
這裡我大概分享一下自己如何確認索引有效性。
相信大家都有聽說過,index key順序會引響效能,
主要是因為統計值所造成,下面是當天活動demo script,
大家可以猜猜看,SQL SERVER查詢優化程式會決定走那一個索引。
--#密度和選擇性
select Rate,PayFrequency,ModifiedDate
from EmployeePayHistory
where PayFrequency=2
and ModifiedDate between '2004-07-31' and '2004-08-10'
drop index idx1 on EmployeePayHistory
create index idx1 on EmployeePayHistory(PayFrequency,ModifiedDate)
include(Rate)
drop index idx2 on EmployeePayHistory
create index idx2 on EmployeePayHistory(ModifiedDate,PayFrequency)
include(Rate)
dbcc show_statistics(EmployeePayHistory,idx1)
dbcc show_statistics(EmployeePayHistory,idx2)
idx1統計值(擷取部分)
PayFrequency 密度0.5
idx2統計值(擷取部分)
ModifiedDate 密度 0.03846154
前面我有說過低密度高選擇性,所以你可能會直覺認定查詢最佳化程式會走idx2 索引,
很不幸你不能只單單做這樣的判斷,因為選擇性主要是因你查詢條件資料分布所決定,
這裡我有一個估算方法。
ModifiedDate between '2004-07-31' and '2004-08-10' 資料分布
符合ModifiedDate 條件資料分布有 277,該索引總筆數 316,所以密度 select (1.0*277)/316
PayFrequency=2 資料分布
符合PayFrequency=2條件資料分布有 136,該索引總筆數 316,所以密度 select (1.0*136)/316
兩個索引密度都算出來,套用之前我所說的,
低密度高選擇性,高選擇性越適合成為nonclustered index key,
所以這次查詢優化程式會使用訪問索引 idx1。
確實使用索引idx1。
當然對於索引優化這只是一小部分,
未來如有機會希望可以和大家分享不求人系列二--索引優化不求人