Index--複合索引的思考1

在建立複合索引時,除了考慮索引鍵的選取外,還需考慮索引鍵的前後順序。下面藉助一些場景來說解。3d


場景1
表dbo.UserLoginStats記錄每一個用戶天天的登陸統計,目前表中存放10億數據,天天新增數據500W(天天每一個用戶不多幾條條記錄),目前系統有用戶8000W,有查詢:
SELECT * FROM dbo.UserLoginStats
WHERE UserID=@userID
AND LoginDay=@loginDay日誌

對於此查詢,能夠建立索引:blog

CREATE INDEX IX_UserID_LoginDay
ON dbo.UserLoginStats(UserID,LoginDay)

CREATE INDEX IX_LoginDay_UserID
ON dbo.UserLoginStats(LoginDay,UserID)索引

以上兩種索引均可以幫助查詢快速返回結果,而且消耗的IO相同,消耗的CPU時間也大體相同,所以對於該查詢來講,兩個索引沒有區別,但咱們該使用哪個查詢呢?隊列

假設索引行每行佔用20個字節,每一個索引頁存放400條記錄,則10億數據須要約2500W個索引頁。
對於索引IX_LoginDay_UserID(LoginDay,UserID):
天天新增的500W新紀錄存放在一塊兒,須要約1.3萬個索引頁來存放,只須要100MB的內存來存放,在數據讀取和寫入時,更多的是順序IO。圖片

對於索引IX_UserID_LoginDay(UserID,LoginDay):
天天新增的500W數據須要分散存放到索引的各個頁面中,可能影響到數百萬的索引頁,須要1GB到5GB的內存,在數據讀取和寫入時,更多的是隨機IO。內存

所以,在不考慮其餘因素影響的條件下,針對該場景,索引IX_LoginDay_UserID(LoginDay,UserID)時最佳的。get


誤區:在建立複合索引時,不少人會將選擇性較高的列放在前面,
解釋:可選擇性是咱們在挑選索引鍵時考慮的一個因素,一般會選擇性較高的備選鍵來建立索引,但不意味該鍵就應該放在索引前面。登錄


PS: 在筆者維護的系統中,曾出現過相似問題,在checkpoint時須要寫入上萬個不連續的數據頁,致使很高的磁盤隊列,同時還致使在日誌備份還原時消耗大量的時間。bfc

PS2:針對該問題,數據分區和歷史數據按期數據歸檔也是很好的解決辦法。

 

慣例上圖引狼

圖片來源:http://www.douban.com/photos/photo/353424799/

相關文章
相關標籤/搜索