1. 程式人生 > >mysql innodb: b+樹 的優點

mysql innodb: b+樹 的優點

我們知道B-樹和B+樹最重要的區別有以下兩點:

1. B+樹中只有葉子節點會帶有指向記錄的指標(ROWID),而B樹則所有節點都帶有,在內部節點出現的索引項不會再出現在葉子節點中。

2. B+樹中所有葉子節點都是通過指標連線在一起,而B樹不會。

B+樹的優點:

1. 非葉子節點不會帶上ROWID,這樣,一個塊中可以容納更多的索引項,一是可以降低樹的高度。二是一個內部節點可以定位更多的葉子節點。

2. 葉子節點之間通過指標來連線,範圍掃描將十分簡單,而對於B樹來說,則需要在葉子節點和內部節點不停的往返移動。

B樹的優點:

對於在內部節點的資料,可直接得到,不必根據葉子節點來定位。

這就決定了B+樹更適合用來儲存外部資料,也就是所謂的磁碟資料。
從Mysql(Inoodb)的角度來看,B+樹是用來充當索引的,一般來說索引非常大,尤其是關係性資料庫這種資料量大的索引能達到億級別,所以為了減少記憶體的佔用,索引也會被儲存在磁碟上。
那麼Mysql如何衡量查詢效率呢?磁碟IO次數,
B-樹
(B類樹)的特定就是每層節點數目非常多,層數很少,目的就是為了就少磁碟IO次數,當查詢資料的時候,最好的情況就是很快找到目標索引,然後讀取資料,使用B+樹就能很好的完成這個目的,但是B-樹的每個節點都有data域(指標),這無疑增大了節點大小,說白了增加了磁碟IO次數(磁碟IO一次讀出的資料量大小是固定的,單個數據變大,每次讀出的就少,IO次數增多,一次IO多耗時啊!),而B+樹除了葉子節點其它節點並不儲存資料,節點小,磁碟IO次數就少。這是優點之一。
另一個優點是什麼,B+樹所有的Data域在葉子節點,一般來說都會進行一個優化,就是將所有的葉子節點用指標串起來。這樣遍歷葉子節點就能獲得全部資料,這樣就能進行區間訪問啦。

至於MongoDB為什麼使用B-樹而不是B+樹,可以從它的設計角度來考慮,它並不是傳統的關係性資料庫,而是以Json格式作為儲存的nosql,目的就是高效能,高可用,易擴充套件。首先它擺脫了
關係模型
,上面所述的優點2需求就沒那麼強烈了,其次Mysql由於使用B+樹,資料都在葉節點上,每次查詢都需要訪問到葉節點,而MongoDB使用B-樹,所有節點都有Data域,只要找到指定索引就可以進行訪問,無疑單次查詢平均快於Mysql(但側面來看Mysql至少平均查詢耗時差不多)。

總體來說,Mysql選用B+樹和MongoDB選用B-樹還是以自己的需求來選擇的。
為什麼B+樹可以滿足要求?  
1) B+-tree的磁碟讀寫代價更低  B+-tree的內部結點並沒有指向關鍵字具體資訊的指標。因此其內部結點相對B 樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入記憶體中的需要查詢的關鍵字也就越多。相對來說IO讀寫次數也就降低了。  舉個例子,假設磁碟中的一個盤塊容納16bytes,而一個關鍵字2bytes,一個關鍵字具體資訊指標2bytes。一棵9階B-tree(一個結點最多8個關鍵字)的內部結點需要2個盤快。而B+ 樹內部結點只需要1個盤快。當需要把內部結點讀入記憶體中的時候,B 樹就比B+ 樹多一次盤塊查詢時間(在磁碟中就是碟片旋轉的時間)。 
 2) B+-tree的查詢效率更加穩定  由於非終結點並不是最終指向檔案內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查詢必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當。
3) “B+樹還有一個最大的好處,方便掃庫,B樹必須用中序遍歷的方法按序掃庫,而B+樹直接從葉子結點挨個掃一遍就完了,B+樹支援range-query非常方便,而B樹不支援。這是資料庫選用B+樹的最主要原因。