天天看點

Mysql資料庫索引的那些事

說起mysql的索引的資料結構,大家一定會想起B+樹,但是在談論索引資料結構之前,有個重要前提必須要清楚。就是:索引的資料結構取決于采用何種存儲引擎。

資料庫的存儲引擎有哪些?

MyISAM:索引結構是B+索引但是采用的是稀疏索引

InnoDB:索引結構也是B+索引,但是采用的是密集索引,詳細看

https://blog.csdn.net/zhaojunwei666/article/details/95892585
           

MERGE:

ARCHIVE:

MEMORY:支援hash索引頁支援B+索引

什麼是hash索引

hash索引是基于hash表實作的,隻有精确比對索引所有列的查詢才有效。對于每一行資料,存儲引擎會根據索隐列計算出一個hash值,和指向該資料行的指針。

如圖:

Mysql資料庫索引的那些事

但是hash索引有着自身局限性:

  • hash索引隻包含hash值和行指針,不存儲字段值,是以不能利用索引的值來避免讀取行
  • hash索引順序不是按照索引值順序存儲的,無法進行排序
  • hash索引不支援所有的部分索引列查找,因為hash值是根據索引索引列計算出來的
  • hash索引隻支援等值比較查詢,如In,=,<>,不支援範圍查詢,如<,>,between
  • 通路hash索引速度非常快。當出現hash沖突,存儲引擎必須周遊連結清單中的所有指針,逐行進行比較
  • hash沖突很高的話,一些索引維護的代價也很高

B+索引與hash索引的比較:

  • B+索引可以根據部分索引進行查找,hash索引必須用全部索引列
  • B+索引存儲字段值,不用讀取行,hash索引不行
  • B+索引支援範圍查詢,hash索引隻支援等值查詢
  • B+索引葉子節點是排序好的連結清單,hash索引無法排序

B樹(balance tree),B+樹:

*** B樹:**

b樹是m階的多路平衡樹,但是從理論來講,二叉樹的查找次數和速度是最小的,為什麼不用二叉樹?

原因有兩點:

1 考慮磁盤IO的影響,每個節點相當于一個磁盤頁,每次通路需要進行一次IO操作,即樹的深度為n,就需要進行n次磁盤IO,顯然存儲同樣多的資料,二叉樹明顯要比b樹高

2 因為二叉樹不是平衡樹,每次增加節點,因為沒有B樹的左旋,右旋機制,可能最後會形成連結清單,導緻時間複雜度o(n),導緻效率太低,是以不采用二叉樹作為索引資料結構。

B樹的每個節點最多有m個子節點,m為b樹的階,一個m階的b樹有如下特點:

  • 任意非葉子節點最多隻有m個孩子節點,m>2
  • 根節點的兒子樹:[2,m]
  • 非葉子節點的關鍵字m-1
  • 所有葉子節點在同一層,非葉子節點包含資料值
  • k個關鍵字把節點分成k+1,分别指向k+1個兒子

有關b樹的一些特性,注意與後面的b+樹區分:

關鍵字集合分布在整顆樹中;

任何一個關鍵字出現且隻出現在一個結點中;

搜尋有可能在非葉子結點結束;

其搜尋性能等價于在關鍵字全集内做一次二分查找;

如圖是一個3階b樹,順便講一下查詢元素5的過程:

Mysql資料庫索引的那些事

1,第一次磁盤IO,把9所在節點讀到記憶體,把目标數5和9比較,小,找小于9對應的節點

Mysql資料庫索引的那些事

2,第二次磁盤IO,還是讀節點到記憶體,在記憶體中把5依次和2、6比較,定位到2、6中間區域對應的節點;

3,第三次磁盤IO就不上圖了,跟第二步一樣,然後就找到了目标5。

b樹的插入删除元素操作:

比如我們要在下圖中插入元素4:

Mysql資料庫索引的那些事

1,首先自頂向下查詢找到4應該在的位置,即3、5之間;

2,但是3階b樹的節點最多隻能有2個元素,是以把3、4、5裡面的中間元素4上移(中間元素上移是插入操作的關鍵);

3,上一層節點加入4之後也超載了,繼續中間元素上移的操作,現在根節點變成了4、9;

4,還要滿足查找樹的性質,是以對元素進行調整以滿足大小關系,始終維持多路平衡也是b樹的優勢,最後變成這樣:

Mysql資料庫索引的那些事

再比如我們要删除元素11:

1,自頂向下查詢到11,删掉它;

2,然後不滿足b樹的條件了,因為元素12所在的節點隻有一個孩子了,是以我們要“左旋”,元素12下來,元素13上去:

Mysql資料庫索引的那些事

這時如果再删除15呢?很簡單,當元素個數太少以至于不能再旋轉時,12直接上去就行了。

B+樹

Mysql資料庫索引的那些事

B+是B樹的一種變體,查詢性能更好,m階B+樹的特點:

  • m階b+樹的非葉子最多有m個孩子,且非葉子節點存儲m個關鍵字,非葉子節點不存儲資料,隻用來做索引,資料都存儲在葉子節點
  • 所有的葉子節點存儲了所有的關鍵字資訊,以及指向含關鍵字記錄的指針,所有葉子節點從小到大順序相連
  • B+樹有兩個指針,一個指向根節點,一個指向關鍵字最小的葉子節點。
  • 同一個數字在不同節點重複出現,根節點的最大關鍵字為b+樹的最大值

B+樹相當于B樹的優勢

  • 非葉子節點不存儲資料,可以存儲更多的關鍵字,會使樹更加矮胖,減少磁盤IO次數,提高通路效率
  • B+樹必須要查到葉子節點才能找到資料,B樹可能在非葉子節點就可以查到
  • 對于查找範圍來說,b+樹隻要周遊葉子節點的連結清單,而b樹需要每次都中序周遊。
    Mysql資料庫索引的那些事
    Mysql資料庫索引的那些事

繼續閱讀