1202索引原理 頁分裂
轉自
http://www.ruzuojun.com/topic/420.html
http://blog.jobbole.com/86594/
http://hedengcheng.com/?p=525
一、innodb存儲引擎索引概述:
innodb存儲引擎支持兩種常見的索引:B+樹索引和哈希索引。
innodb支持哈希索引是自適應的,innodb會根據表的使用情況自動生成哈希索引。
B+樹索引就是傳統意義上的索引,是關系型數據庫中最常用最有效的索引。B+樹是從最早的平衡二叉樹演變而來,但是B+樹不是一個二叉樹。B+中的B不代表二叉(Binary),而是代表平衡(Balance)。
注意:B+樹索引並不能找到一個鍵值對應的具體行。b+樹索引只能查到被查找數據行所在的頁,然后數據庫通過把頁讀入內存,再在內存中查找,最后得到結果。
二、理解B+樹算法
B+樹是為磁盤及其他存儲輔助設備而設計一種平衡查找樹(不是二叉樹)。B+樹中,所有記錄的節點按大小順序存放在同一層的葉節點中,各葉節點用指針進行連接。
下面演示一個B+數結構,高度為2,每頁可放4條記錄,扇出(fan out)為5。從下圖1可以看出,所有記錄都在頁節點中,並且為順序存放,我們從最左邊的葉節點開始遍歷,可以得到所有鍵值的順序排序:5、10、15、20、25、30、50、55、60、65、75、80、85、90.
圖1 高度為2的B+樹
(1) B+樹的插入操作
B+樹的插入必須保證插入后葉節點的記錄依然排序。同時要考慮插入B+樹的三種情況,每種情況都可能導致不同的插入算法。如下表所示:
我們實例分析B+樹的插入,在圖1的B+樹中,我們需要插入28這個值。因為Leaf Page和Index page都沒有滿,我們直接將記錄插入葉節點就可以了。如下圖2所示:
圖2 插入鍵值28
下面我們再插入70這個值,這時Leaf Page已經滿了,但是Index Page還沒有滿,符合上面的第二種情況。這時插入Leaf Page的情況為
50、55、60、65、70.我們根據中間的值60拆分葉節點,可得到下圖3所示(雙項鏈表指針依然存在,沒有畫出):
圖3 插入鍵值70
最后我們再插入95,這個Leaf Page和Index Page都滿了,符合上面第三種情況。需要做2次拆分,如下圖4所示:
圖4 插入鍵值95
可以看到,不管怎么變化,B+樹總會保持平衡。但是為了保持平衡,對於新插入的鍵值可能需要做大量的拆分頁操作。B+樹主要用於磁盤,拆分意味着磁盤的操作,應該在可能的情況下盡量減少頁的拆分。因此,B+樹提供了旋轉功能。旋轉發生在Leaf Page已經滿了,但是左右兄弟節點沒有滿的情況下。這時B+樹並不是急着做頁的拆分,而是旋轉。旋轉結果如圖5所示,可以看到旋轉操作使B+樹減少了一次頁的拆分操作,高度仍然為2.
圖5 B+樹的旋轉操作
(2) B+樹的刪除操作
B+樹使用填充因子來控制數的刪除變化。填充因子可以設置的最小值為50%。B+樹的刪除操作同樣保證刪除后葉節點的記錄依然排序。
根據填充因子的變化,B+樹刪除依然需要考慮三種情況,如下表所示:
根據圖4的B+樹,我們進行刪除操作,首先刪除鍵值為70的這條記錄,該記錄符合上表第一種情況,刪除后如下圖6所示:
圖6 刪除鍵值70
接着我們刪除鍵值為25的記錄,這也是屬於上表第一種情況,不同的是該值還是index page中的值。因此在刪除Leaf Page中的25后,還需要將25的右兄弟節點28更新到Index Page中,如下圖7所示(圖中有兩個筆誤,紅色為修正值):
圖7 刪除鍵值28
最后我們刪除鍵值為60的記錄。刪除Leaf page鍵值為60的記錄后,其填充因子小於50%。需要做合並操作。同樣在刪除Index page中相關記錄后需要做Index Page的合並操作。
三、B+樹索引介紹
B+樹索引的本質是B+樹在數據庫中的實現。但是B+樹索引有一個特點是高扇出性,因此在數據庫中,B+樹的高度一般在2到3層。也就是說查找某一鍵值的記錄,最多只需要2到3次IO開銷。按磁盤每秒100次IO來計算,查詢時間只需0.0.2到0.03秒。
數據庫中B+樹索引分為聚集索引(clustered index)和非聚集索引(secondary index).這兩種索引的共同點是內部都是B+樹,高度都是平衡的,葉節點存放着所有數據。不同點是葉節點是否存放着一整行數據。
