複合索引是利用多個欄位來組成索引。
利用 AdventureWorks2012 內的 Person 資料表的非叢集式索引(NonClustered Index,簡稱索引) IX_Person_LastName_FirstName_MiddleName 來說明欄位順序的影響。
IX_Person_LastName_FirstName_MiddleName 索引是由 LastName、FirstName 和 MiddleName 三個欄位依序組成
從 Person 資料表中選定一位人名針對三個欄位組合來搜尋資料並觀察 Query Optimizer(簡稱 QO) 選擇執行計畫時使用索引的狀態
- 針對 LastName、FirstName 和 MiddleName 搜尋
SELECT LastName , FirstName , MiddleName
FROM [Person].[Person]
WHERE LastName = 'Ting' AND FirstName = 'Hung-Fu' AND MiddleName = 'T'
- 針對 LastName 和 MiddleName 搜尋
SELECT LastName , FirstName , MiddleName
FROM [Person].[Person]
WHERE LastName = 'Ting' AND MiddleName = 'T'
- 針對 FirstName 和 MiddleName 搜尋
SELECT LastName , FirstName , MiddleName
FROM [Person].[Person]
WHERE FirstName = 'Hung-Fu' AND MiddleName = 'T'
從上面三個例子可以看出搜尋條件中有包含 LastName 欄位的話,QO 會利用索引搜尋(Index Seek)來搜尋資料,沒有的話則是利用索引掃描(Index Scan)。
複合索引(IX_Person_LastName_FirstName_MiddleName)雖由多個欄位組成,但其資料在索引分頁( Index Page)上,只有第一個欄位(LastName)資料是經過排序。下圖是擷取 Person 資料表內部分資料,來模擬資料在索引分頁(Index Page)上的理論資料排序情況。
而從統計資訊來觀察,會發現複合索引統計資訊內只會保存第一個欄位(LastName )的資料長條圖(Histogram)
複合索引的第一個欄位選擇非常重要,因為它是唯一一個欄位資料有經過排序,且能發揮複合索引效能的關鍵。