建立[具有內含資料行的索引](文內簡稱包含索引)來滿足 Covering Index 進而消除 Key Lookup 來提高效能,就是此篇文章要說明的
建立包含索引的簡易語法
CREATE INDEX IndexName
ON SchemaName.TableName (Col1,Col2,Col3.......)
INCLUDE (ColA,ColB,ColC.......)
利用 AdventureWork 的 Sales.SalesOrderHeader 來說明-- Step 1:針對 OrderDate 建立 nonclustered index
CREATE INDEX IX_OrderDate ON [Sales].[SalesOrderHeader] (OrderDate)
-- Step 2:找出 OrderDate = '20040729' 的 SalesOrderID、OrderDate 和 CustomerID 這三個欄位資料
SELECT
SalesOrderID ,
OrderDate ,
CustomerID
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = '20040729'
下圖為 Step 2 執行計畫,可以看出因為 IX_OrderDate 無法滿足 Covering Index 所以利用 Clustered Index 搭配 Nested Loop(巢狀迴圈)一筆一筆資料進入PK_SalesOrderHeader_SalesOrderID 抓取資料把滑鼠移到[索引鍵查閱]上,會顯示下列資訊,可以觀察到是為了要找 CustomerID 資料(綠色框框),所以利用[索引鍵查閱](紅色框框)進入PK_SalesOrderHeader_SalesOrderID (綠色框框)抓取資料
-- Step 3:刪除 IX_OrderDate
DROP INDEX IX_OrderDate ON [Sales].[SalesOrderHeader]
-- Step 4:建立包含索引
CREATE INDEX IX_OrderDate
ON [Sales].[SalesOrderHeader] (OrderDate)
INCLUDE (CustomerID) -- 包含 CustomerID 欄位
-- Step 5:再次執行查詢語法
SELECT
SalesOrderID ,
OrderDate ,
CustomerID
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = '20040729'
下圖為 Step 5 執行計畫,可以觀察到因為 CustomerID 已經包含在 IX_OrderDate 內,不再需要[索引鍵查閱]去搜尋資料Key Lookup 只會利用 Nested Loop 來抓取資料,是一個極耗成本的動作,是進行 Perfomance Tuning 時的觀察重點,而除了建立包含索引來避免,撰寫 T-SQL 語法時,也要避免抓出不必要的資料,SELECT * 的寫法更是大忌喔
- 2011 SQL Hero
沒有留言:
張貼留言