上一篇文章《MySQL索引爲何要用B+樹》講了MySQL爲何選擇用B+樹來做爲底層存儲結構,提了兩個知識點:sql
爲進一步知其因此然,今天來聊聊B+樹索引在物理磁盤上是怎麼設計存儲的。性能
衆所周知,MySQL的數據實際是存儲在文件中,而磁盤IO的查找速度是要遠小於內存速度的,因此減小磁盤IO的次數能很大程度的提升MySQL性能。ui
先溫習下知識點:磁盤IO時間 = 尋道 + 磁盤旋轉 + 數據傳輸時間spa
從磁盤讀取數據時,系統會將邏輯地址發給磁盤,磁盤將邏輯地址轉換爲物理地址(哪一個磁道,哪一個扇區)。 磁頭進行機械運動,先找到相應磁道,再找該磁道的對應扇區,扇區是磁盤的最小存儲單元(見圖1-1
)。設計
機械硬盤的連續讀寫性能很好,但隨機讀寫性能不好。指針
kafka
的特色,之後有機會的話再講一講)隨機讀寫時,磁頭須要不停的移動,時間都浪費在了磁頭尋址上。 而在實際的磁盤存儲裏,是不多順序存儲的,由於這樣的維護成本會很高。code
知道磁盤IO的性能了吧,接下來看看MySQL是如何根據這種狀況來設計索引的物理存儲,如下內容以InnoDB
引擎爲例,MyISAM
略有不一樣,後面再講。orm
假設咱們有一張這樣的表,表中有如圖2-0
的數據cdn
CREATE TABLE `user` (
`ID` bigint(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(20),
PRIMARY KEY (`ID`),
KEY `idx_name` (`NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
複製代碼
每一個InnoDB表都有一個稱爲彙集索引的特殊索引,該索引是按照表的主鍵構造的一棵B+樹。blog
根據示例數據構建如圖2-1所示彙集索引:
這裏只進行了兩次IO,實際上,每一個磁盤塊大小爲4K,3層的B+樹能夠表示上百萬的數據,也就是每次查找只須要3次IO,因此索引對性能的提升將是巨大的。
每張InnoDB表有且只有一個彙集索引,那它是怎麼選擇索引的呢?
PRIMARY KEY
來做爲彙集索引。PRIMARY KEY
,將會用第一個UNIQUE
且NOT NULL
的列來做爲彙集索引。UNIQUE
索引,會內部根據行ID值生成一個隱藏的聚簇索引GEN_CLUST_INDEX
。因此在建表的時候,若是沒有邏輯惟一且非空列時,能夠添加一個auto_increment的列,方便創建一個彙集索引。
非彙集索引又叫輔助索引,葉子節點並不包含行記錄數據,而是存儲了彙集索引鍵。
根據示例數據(idx_name
索引)構建如圖2-2所示輔助索引:
NAME=Jake
的數據第一階段:經過輔助索引查到主鍵索引的主鍵
第二階段:經過主鍵索引找到完整的行記錄
查找結束。
未完待續…
若是想要實時關注更新的文章以及分享的乾貨,能夠關注個人公衆號