b+樹索引並不能直接找到行,只是找到行所在的頁,通過把整頁讀入記憶體,再在記憶體中查詢。
索引的b+樹高度一般為2-4層,查詢記錄時最多隻需要2-4次io。
為進一步知其所以然,今天來聊聊b+樹索引在物理磁碟上是怎麼設計儲存的。
眾所周知,mysql的資料實際是儲存在檔案中,而磁碟io的查詢速度是要遠小於記憶體速度的,所以減少磁碟io的次數能很大程度的提高mysql效能。
先溫習下知識點:磁碟io時間 = 尋道 + 磁碟旋轉 + 資料傳輸時間
從磁碟讀取資料時,系統會將邏輯位址發給磁碟,磁碟將邏輯位址轉換為實體地址(哪個磁軌,哪個扇區)。 磁頭進行機械運動,先找到相應磁軌,再找該磁軌的對應扇區,扇區是磁碟的最小儲存單元(見圖1-1
)。
 圖1-1 磁碟物理結構機械硬碟的連續讀寫效能很好,但隨機讀寫效能很差。
隨機讀寫時,磁頭需要不停的移動,時間都浪費在了磁頭定址上。 而在實際的磁碟儲存裡,是很少順序儲存的,因為這樣的維護成本會很高。
知道磁碟io的效能了吧,接下來看看mysql是如何根據這種情況來設計索引的物理儲存,以下內容以innodb
引擎為例,myisam
略有不同,後面再講。
假設我們有一張這樣的表,表中有如圖2-0
的資料
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;
複製**
圖2-0 表資料每個innodb表都有乙個稱為聚集索引的特殊索引,該索引是按照表的主鍵構造的一棵b+樹。
根據示例資料構建如圖2-1所示聚集索引:
 圖2-1 b+樹聚集索引
2.1.1 知識點
2.1.2 查詢:假設要查詢資料項6
把根節點由磁碟塊0載入到記憶體,發生一次io,在記憶體中用二分查詢確定6在3和9之間;
通過指標p2的磁碟位址,將磁碟2載入到記憶體,發生第二次io,再在記憶體中進行二分查詢找到6,結束。
這裡只進行了兩次io,實際上,每個磁碟塊大小為4k,3層的b+樹可以表示上百萬的資料,也就是每次查詢只需要3次io,所以索引對效能的提高將是巨大的。
2.1.3 怎樣選擇聚集索引
每張innodb表有且只有乙個聚集索引,那它是怎麼選擇索引的呢?
所以在建表的時候,如果沒有邏輯唯一且非空列時,可以新增乙個auto_increment的列,方便建立乙個聚集索引。
非聚集索引又叫輔助索引,葉子節點並不包含行記錄資料,而是儲存了聚集索引鍵。
根據示例資料(idx_name
索引)構建如圖2-2所示輔助索引:
 圖2-2 b+樹非聚集索引
2.2.1 知識點
2.2.2 查詢:獲取name=jake
的資料
第一階段:通過輔助索引查到主鍵索引的主鍵
把idx_name索引的根節點由磁碟塊0載入到記憶體,發生一次io,查詢到在p2指標中
根據p2指標的磁碟位址,載入磁碟塊2到記憶體,發生第二次io,查詢到jake節點以及它的主鍵索引9
第二階段:通過主鍵索引找到完整的行記錄
把根節點由磁碟塊0載入到記憶體,發生一次io,在記憶體中用二分查詢確定9在p3指標中
通過指標p3的磁碟位址,將磁碟3載入到記憶體,發生第二次io,再在記憶體中進行二分查詢找到9,以及它的行記錄,
查詢結束。
未完待續…
MySQL 索引中的b樹索引
1.索引如果沒有特別指明型別,一般是說b樹索引,b樹索引使用b樹資料結構儲存資料,實際上很多儲存引擎使用的是b 樹,每乙個葉子節點都包含指向下乙個葉子節點的指標,從而方便葉子節點的範圍遍歷 2.底層的儲存引擎也可能使用不同的儲存結構,比如ndb集群儲存引擎使用了t樹,innodb使用的是b 樹 3....
Mysql中的B樹索引和B 樹索引的區別?
參考原文 b樹可以在內部節點同時儲存鍵和值,因此,把頻繁訪問的資料放在靠近根節點的地方將會大大提高熱點資料的查詢效率。這種特性使得b樹在特定資料重複多次查詢的場景中更加高效。由於b 樹的內部節點只存放鍵,不存放值,因此,一次讀取,可以在記憶體頁中獲取更多的鍵,有利於更快地縮小查詢範圍。b 樹的葉節點...
B樹 B樹的特性及B樹在磁碟檔案中的應用
二叉查詢樹乙個結點乙個key 2 3樹乙個結點最多可以有兩個key 紅黑樹乙個結點乙個key,但通過對鏈結染紅色的方式去表達乙個結點兩個key,間接實現了2 3樹。b樹也是一種樹型結構,它的乙個結點可以有多於兩個key的存在,它能夠儲存資料 對資料排序並允許以o logn 的時間複雜度進行查詢 順序...