MySQL之InnoDB索引面試學習筆記


寫在前面

  想要做好后台開發,終究是繞不過索引這一關的。先問自己一個問題,InnoDB為什么選擇B+樹作為默認索引結構。本文主要參考MySQL索引背后的數據結構及算法原理剖析Mysql的InnoDB索引

 

索引

  當數據量到達一定規模時,我們通常會對經常使用的字段建立索引,來加快數據的查詢。首先需要強調的是索引的本質是數據結構,前輩們經過不斷完善得到了幾種復雜度較低並且能夠降低磁盤IO的數據結構,這里要說的是B樹與B+樹,他們被廣泛應用在文件系統與數據庫系統中。

B-Tree

   B樹邏輯上是一顆多叉樹,3階B樹如下:

                                 

  m階B樹滿足以下幾個條件:

  • 非葉子節點最少有m/2顆子樹(即B樹的度為m/2)
  • 葉子節點在同一層,每個節點最多有m-1個升序排列的key(索引列)和m個指針,key與指針相互間隔

搜索二叉樹的查詢復雜度為O(log2N),而B樹的復雜度為O(logm/2N),對於N=62*1000000000個節點,如果度為1024,則logM/2N <=4,可以說它是效率很高的數據結構。

B+樹

   B+樹是B樹的變種,區別有三點:

  • 非葉子節點只存儲key,不存儲data;葉子節點存儲所有key與data,不存儲指針
  • 葉子節點增加了順序訪問指針
  • 每個節點最多有m個升序排列的key

                 

 

  上述區別換來的優點包括:

  • 非子節點可以存放更多的key,具有更好的空間局部性,提高緩存命中率
  • 葉子節點相鏈便於區間查找,順序查找替代B樹的遞歸查找。

為什么選擇B+樹

  首先要意識到數據檢索的時間主要耗費在磁盤IO(尋道時間、旋轉時間)上,因此要盡量減少IO次數。對樹形結構的數據來說,樹的每一層代表需要一次磁盤IO查詢,因此設計了“扁平”的B樹與更扁的B+樹。另外,由著名的局部性原理,訪問的數據通常比較集中,磁盤每次IO時會預讀數據,預讀的長度為頁(4k)的整數倍,B/B+樹新建節點會申請一個頁的空間,因此取一個節點只需要一次IO(非葉子節點可存儲到內存中)。

                     

 

索引創建過程

mysql創建索引是通過online create index,減少業務停寫時間,創建索引期間業務能正常工作。

步驟:

  1. 等待當前所有事務執行結束;新事務更新數據會把新建索引記錄到Row Log中
  2. 構建索引,從主表讀出數據並排序。使用臨時文件進行外部排序方式,單線程兩路歸並。
  3. 把增量數據從Row Log更新到索引表中

MySQL存儲引擎 

首先區分聚簇索引(按主鍵聚集)與非聚簇索引:

                      

  • 二者使用B+樹作為數據結構
  • 聚簇索引的data存於主鍵索引的葉子節點中,得到key同時得到data,非聚簇索引數據存於獨立的地方,葉節點保存的是數據的地址
  • 聚簇索引的輔助鍵索引(非主鍵索引,例如employee表中對name建索引)葉節點存儲主鍵而非數據(為了節省空間,缺陷是需要到主鍵索引中二次查詢);非聚簇索引葉節點保存數據的地址。

  聚簇索引的優勢在於找到主鍵同時得到data,省去二次磁盤IO;另外B+樹在插入或刪除節點時周圍節點地址會發生變化,對非聚簇索引來說需要更新所有B+樹的地址指針,增加開銷。

InnoDB

  InnoDB使用聚簇索引(MyISAM使用非聚簇索引),其磁盤管理邏輯單位是Page(不同於上述內存中的頁!),每個Page大小為16k,使用32位int標識,對應innoDB最大64TB的存儲容量。

  每個Page包括頭部、主體、尾部三部分:

                            

  其中頭部包括id與相鄰Page指針(構成雙向鏈表);

  主體即B+樹節點的存儲,其中包括很多Record(節點)包括四類:

  • 主索引非葉子節點:定位Page
  • 主索引葉子節點:包括key與該key對應的所有列(mysql表中的一行)
  • 輔助索引非葉子節點:定位Page
  • 輔助索引葉子節點:包括索引鍵值與主鍵值(key)

  

  主鍵選擇

  因為數據存於主索引中,要求一個節點的各條數據記錄按主鍵順序存放,當一頁達到裝載因子(15/16)會自動開辟新的頁。如果使用自增主鍵,每次插入新紀錄都順序添加到索引節點的后續位置,否則會節點中key會一直移動。

  最左匹配原則

  在聯合索引中對a,b兩個字段建立索引(a, b),在查詢時只有包括a時才會查詢索引。

                 

  如上圖(a, b)聯合索引,在a相同時,b按順序排列。在遇到范圍查詢時之后的字段會停止匹配。因為a是范圍,b無序。  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM