前文
本系列文章
兩種基本索引
- Clustered Index(叢集索引)
- NonClustered Index(非叢集索引)
兩種Lookup
(如果NonClustered Index
無法滿足查詢結果執行)
- RID Lookup
- Key Lookup
本篇會介紹其他種類Index
Covering Index
我們先來看看Covering Index
語法.
最主要使在NONCLUSTERED INDEX
後面加上INCLUDE
欄位.
CREATE NONCLUSTERED INDEX IX_T_Id_Convering on dbo.T(
id
) INCLUDE (
UserId,
UserGroup
)
加入INCLUDE欄位含意
在NONCLUSTERED INDEX
把Column
加入INCLUDE
區域後此NONCLUSTERED INDEX
會把此欄位資料加入至子頁層.之後如果要查找資料時就不用在Lookup
回去
所以我們可以把
Covering Index
當作是偽CLUSTERED INDEX
.
如果每次只需要
SELECT
少部分欄位且範圍較大又須排序,Covering Index
執行效率會比CLUSTERED INDEX
來的快.
適合Covering Index
很適合用在查出來Column
不需要當作Key
案例解說
樣本資料一樣使用上一篇的資料
SELECT *
FROM dbo.T
WHERE id = 10000
SELECT *
FROM dbo.T with(index(IX_T_Id))
WHERE id = 10000
有兩段語法一段是有使用Hint
,執行出來後會有兩個執行計畫.
第一個執行計畫是上面的語法,第二個執行計畫是下面的語法
建立完Convering Index
後我們使用的查詢就會變成只使用Seek
,而且在執行成本也大幅降低.
Filter Index
Filter Index
語法就是在最後寫where
條件
CREATE NONCLUSTERED INDEX FIX_T_Id_UserGroup on dbo.T(
id
) INCLUDE (
UserId,
UserGroup
)
where UserGroup = 8
上面語法意思是只針對於UserGroup = 8
的Row
建立資料在子頁層,Filter Index
主要是提升維護性和降低Index
大小.
注意:如果有使用到
Filter Index
的SP
或Script
,如果沒有加上SET QUOTED_IDENTIFIER ON
就會造成錯誤,所以在撰寫Script
時要養成加上上面語法的好習慣.
Index Intersection
SQL-Server
可透過多個Index
完成一段查詢(通常選擇子集合較小)在透過JOIN
完成查詢
假如我們有兩個一個查詢會用到UserId
和Id
Column當作條件我們可能會建立下面這個索引.
CREATE CLUSTERED INDEX IX_T_UserId_Id on dbo.T(
UserId,
Id
)
但除了同時利用UserId
和Id
Column當作條件外還可能個別當作查詢條件.
我們就可以考慮把這個Index
拆開成兩個,這樣可以提高索引使用率(因為執行計畫透過統計值來產生,而Index
統計值計算是由Index
第一個Column來當計算)
注意:把
Index
猜成兩個或許可以增加查詢效率,但每個Index
就是一個B+ Tree
這會造成
CREATE CLUSTERED INDEX IX_T_UserId on dbo.T(
UserId
)
CREATE CLUSTERED INDEX IX_T_Id on dbo.T(
Id
)
Primary Key
在SQL-Server
很常使用PRIMARY KEY但你知道他代表甚麼含意嗎?
PRIMARY KEY是也是一個Index
,他可以設定NonClustered Index
或是Clustered Index
PRIMARY KEY有幾個特徵
- 資料不能重複(Unique)
- Columns都必須定義成
NOT NULL
- PRIMARY KEY是一個
Index
預設建立的PRIMARY KEY是
Clustered Index
,但我們使用語法自行建立為NonClustered Index
的PRIMARY KEY
如下範例我們可以建立一個NONCLUSTERED
的PRIMARY KEY
CREATE TABLE T(
ID INT NOT NULL,
CONSTRAINT [PK_T] PRIMARY KEY NONCLUSTERED (
ID
)
)
如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^