在建立復合索引時,除了考慮索引鍵的選取外,還需考慮索引鍵的先後順序。下面借助一些場景來講解。
場景1表dbo.userloginstats記錄每個使用者每天的登入統計,目前表中存放10億資料,每天新增資料500w(每天每個使用者很少幾條條記錄),目前系統有使用者8000w,有查詢:
select * from dbo.userloginstats
where userid=@userid
and loginday=@loginday
對於此查詢,可以建立索引:
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)時最佳的。
誤區:在建立復合索引時,很多人會將選擇性較高的列放在前面,
解釋:可選擇性是我們在挑選索引鍵時考慮的乙個因素,通常會選擇性較高的備選鍵來建立索引,但不意味該鍵就應該放在索引前面。
ps: 在筆者維護的系統中,曾出現過類似問題,在checkpoint時需要寫入上萬個不連續的資料頁,導致很高的磁碟佇列,同時還導致在日誌備份還原時消耗大量的時間。
ps2:針對該問題,資料分割槽和歷史資料定期資料歸檔也是很好的解決辦法。
慣例上圖引狼
mysql復合索引怎麼理解 關於復合索引的一些理解
前面單獨寫了關於復合索引中的最左字首原則的仔細分析,接下來我們就復合索引進行更深一步的了解。這裡的復合索引指的就是組合索引。首先,我們重溫一下復合索引的基本概念,就是在兩個及以上字段建立乙個索引。它的存在主要是為了多條件的查詢,比如說where後面加了好幾個條件,乙個是a欄位相關的,乙個是b欄位相關...
MySQL的索引(Index)詳解
索引分類 1 普通索引 key indexes 2 唯一索引 unique indexes 3 主鍵索引 primary key indexes 4 組合索引 composite index 5 字首索引 prefix indexes 6 全文索引 full text indexes 7 雜湊索引 ...
C foreach 中獲取索引index的方法
在c 開發中往往使用foreach 迴圈語句 來代替for迴圈語句。foreach 比 for 更加簡潔高效。foreach foreach var item in arr for for int i 0 i 顯然 for語句直接就存在索引變數,通過索引獲取值。但在實際操作中,使用foreach 有...