[SQL SERVER]複合索引第一欄位重要性

[SQL SERVER]複合索引第一欄位重要性

前幾天幫以前同事調校SQL 2012效能,整個系統雖然都沒有任何遺漏索引,但是相關複合索引選擇性卻不夠嚴謹

說白話一點就是索引設計不良,由於SQL Server中只會對第一個欄位(index key)存放統計值,

所以如果第一個欄位的選擇性過低或是查詢類型不符,那麼其實該索引對查詢效能就無明顯助益,下面我簡單測試

TSQL

select ProductID,ReferenceOrderLineID,TransactionType,Quantity

,TransactionDate

from [dbo].[TransactionHistory]

where

ProductID>=784 and ProductID<=990

and

ReferenceOrderLineID=0

and TransactionType='W'

and Quantity>0

 

範圍查詢不適合使用nonclustered index(適用clustered index),ReferenceOrderLineID和TransactionType兩個欄位比較起來

ReferenceOrderLineID選擇性比較高,所以第一欄位使用ReferenceOrderLineID會比較好,

下面我建立3種nonclustered index實際比較看看效能如何

 

create index idx1 on [dbo].[TransactionHistory](ProductID,TransactionType,Quantity,ReferenceOrderLineID)

include(TransactionDate)

create index idx2 on [dbo].[TransactionHistory](ReferenceOrderLineID,TransactionType,ProductID,Quantity)

include(TransactionDate)

create index idx3 on [dbo].[TransactionHistory](TransactionType,ReferenceOrderLineID,ProductID,Quantity)

include(TransactionDate)

 

 

--idx1 原本使用索引
select ProductID,ReferenceOrderLineID,TransactionType,Quantity

,TransactionDate

from [dbo].[TransactionHistory] with(index(idx1))

where

ProductID>=784 and ProductID<=990

and

ReferenceOrderLineID=0

and TransactionType='W'

and Quantity>0

--idx2
select ProductID,ReferenceOrderLineID,TransactionType,Quantity

,TransactionDate

from [dbo].[TransactionHistory] with(index(idx2))

where

ProductID>=784 and ProductID<=990

and

ReferenceOrderLineID=0

and TransactionType='W'

and Quantity>0

--idx3
select ProductID,ReferenceOrderLineID,TransactionType,Quantity

,TransactionDate

from [dbo].[TransactionHistory] with(index(idx3))

where

ProductID>=784 and ProductID<=990

and

ReferenceOrderLineID=0

and TransactionType='W'

and Quantity>0

 

image

image

可以看到原本使用的索引邏輯讀取較高(309),以這TSQL來說,

第一個欄位選擇ReferenceOrderLineID(選擇性較高)會是較好設計。