測試表結構:後端
CREATE TABLE TB1 ( ID INT IDENTITY(1,1), C1 INT, C2 INT )
1. 彙集索引(Clustered index)測試
彙集索引能夠理解爲一個包含表中除索引鍵外多有剩餘列的包含索引,爲保證在DELETE/UPDATE操做的正確性,若是彙集索引未聲明爲惟一(UNIQUE),則系統會彙集索引鍵增長一個NULLABLE的INT類型標識列(UNIQUIFIER)以保證記錄惟一性。spa
惟一彙集索引:3d
CREATE UNIQUE CLUSTERED INDEX IDX_ID ON TB1 ( ID )
非惟一彙集索引:code
CREATE CLUSTERED INDEX IDX_ID ON TB1 ( ID )
2. 非惟一非彙集索引blog
爲從非彙集索引定位到數據,對於堆表,非彙集索引會存放索引鍵+數據的RID(FILE_ID+PAGE_ID+SLOT_ID),對於彙集表,非彙集索引會存放索引鍵+彙集索引鍵。排序
非彙集索引:索引
CREATE INDEX IDX_C1 ON TB1 ( C1 )
堆表上非彙集索引:資源
惟一彙集索引表上非彙集索引:產品
非惟一彙集索引表非彙集索引:
--==============================
後續的測試默認使用惟一彙集索引
--==============================
3. 惟一非彙集索引
惟一非彙集索引與非惟一非彙集索引的區別主要在非葉子節點上,惟一非彙集索引的非葉子節點上不會包含RID的數據。
惟一非彙集索引:
CREATE UNIQUE INDEX IDX_C1_UNI ON TB1 ( C1 )
4. 包含索引
包含索引在SQL SERVER 2008版本中引入,包含列的數據只存在在葉子節點上。包含列不影響索引行的位置(不會被排序),且包含列不會影響索引鍵的大小(SQL SERVER 限制索引鍵不得超過900字節)
CREATE INDEX IDX_C1_INC_C2 ON TB1 ( C1 )INCLUDE ( C2 )
5. 過濾索引
當過濾列不做爲索引鍵或包含列時,系統無需在索引中存放過濾列的數據,所以過濾列不會出如今索引的葉子節點和非葉子節點上。
CREATE INDEX IDX_C1_WH_C2 ON TB1 ( C1 ) WHERE C2>1
--=============================================================
總結&建議:
1. 對於彙集表,因爲索引非彙集索引都會包含彙集鍵,所以建議優先考慮靜態+惟一+遞增+長度較小的索引鍵做爲索引鍵
a. 靜態:當彙集鍵被更新時,除了將表數據移動到相應的位置上,依次更新全部的非彙集索引,會消耗大量資源,並致使頁拆分和索引碎片
b. 惟一: 非惟一彙集索引增長2至6個字節的消耗,致使彙集索引和非彙集索引消耗更多頁面
c. 遞增:對於非遞增的彙集索引鍵來講,插入操做會引起頁拆分和索引碎片
d. 長度較小:長度較大的彙集索引鍵一樣會致使彙集索引和非彙集索引消耗更多頁面,尤爲是致使索引層數增長,增長INDEX SEEK的開銷。
2. 索引列的可選擇性和索引列順:高選擇性不表明該列就適合放在索引前部,還應該考慮針對該列是範圍查詢仍是等值查詢,如訂單表的建立時間列CreatedTime主要用做範圍查詢,而訂單表的產品編號ProductID主要用等值查詢,那麼對於
WHERE ProductID=@P1 AND CreatedTime>@P2 AND CreatedTime<@p3
這樣的查詢,索引 INDEX(ProductID,CreatedTime)就會比INDEX(CreatedTime,ProductID) 更高效(消耗更少的CPU和IO資源)。
3. 索引列順序與統計:索引列前後順序不一樣,其對於的統計信息的密度(density)和直方圖(histogram)也不相同,會間接影響到生成的執行計劃。
4. 對於選擇性較低且位於索引列後端的列來講,能夠考慮將其放入到包含索引列中。
5. 雖然過濾索引在統計信息更新方面存在必定的問題,過濾索引依然是解決部分疑難雜症的必殺技(如SELECT TOP(10) * FROM orders WHERE ProductID>10000 ORDER BY OrderID DESC)
6. 在對遞增的列創建索引時,應考慮統計過時致使執行計劃低效的問題,如對訂單表上建立日期列創建索引。
--==========================================================
寫得很差,靠妹子加分啦。。