(轉)MySQL索引背後的數據結構及算法原理

原文:https://www.kancloud.cn/kancloud/theory-of-mysql-index/41846html

         http://blog.leanote.com/post/804305986@qq.com/b1bcd4f82d6bmysql

MySQL索引背後的數據結構及算法原理算法

 

MySQL索引背後的數據結構及算法原理
 深刻理解mysql     2016-08-07 19:15:45     228     0     0
  1. MySQL索引背後的數據結構及算法原理

前言

  • MySQL數據庫支持多種索引類型,如BTree索引,哈希索引,全文索引等等。本文只關注於BTree索引

數據結構及算法基礎

索引的本質

  • 索引的定義索引是一類數據結構,用於幫助MySQL高效的獲取數據。sql

    數據庫系統維護着知足特定查找算法的數據結構,這些數據結構以某種方式指向數據,這樣就能夠在這些數據結構上實現高級查找算法。這種數據結構,就是索引。數據庫

     
    上圖展現了一種可能的索引方式:左邊是數據表,一共有兩列七條記錄,最左邊的是數據記錄的物理地址(注意邏輯上相鄰的記錄在磁盤上也並非必定物理相鄰的)。爲了加快Col2的查找,能夠維護一個右邊所示的二叉查找樹,每一個節點分別包含索引鍵值和一個指向對應數據記錄物理地址的指針,這樣就能夠運用二叉查找在θ(log2n)θ(log2⁡n)的複雜度內獲取到相應數據。雖然這是一個貨真價實的索引,可是實際的數據庫系統幾乎沒有使用二叉查找樹或其進化品種紅黑樹實現的,緣由在於樹的深度太高所致使的IO次數過多數據結構

經常使用的樹型索引

B-Tree

  • B-Tree的定義與特徵:B-Tree中的每一個結點都保存一組二元組[key, data],其中key爲關鍵字,data爲除key之外的數據。post

    • B樹又叫平衡多路查找樹,一棵m階的B樹有以下特徵: 
      1. 根結點有[2,m][2,m]個子樹,非根內部結點有[m/2,m][⌈m/2⌉,m]個子樹。
      2. 全部葉子結點(空結點)都出如今同一層。
      3. 假設每一個非終端結點中包含有n個關鍵字信息:{p0,k1,p1,k2,p2,...,kn,pn}{p0,k1,p1,k2,p2,...,kn,pn},其中kiki爲關鍵字且關鍵字按順序升序排序,pipi爲指向子樹的結點,則指針pi1pi−1所指向子樹中的全部結點的關鍵字均處於(ki1,ki)(ki−1,ki)範圍內 —— 最左子樹無下限,最右子樹無上限

B+Tree

  • MySQL廣泛使用B+Tree實現其索引結構。
  • B+Tree的定義與特徵:B+Tree中的每一個內結點都保存一組關鍵字,而data只存於葉子結點中。性能

    • B+樹又叫平衡多路查找樹,一棵m階的B+樹有以下特徵: 
      1. 根結點有[2,m][2,m]個子樹,非根內部結點有[m/2,m][⌈m/2⌉,m]個子樹。
      2. 全部葉子結點(保存data的結點)都出如今同一層。
      3. 假設每一個非終端結點中包含有n個關鍵字信息:{k1,p1,k2,p2,...,kn,pn}{k1,p1,k2,p2,...,kn,pn},其中kiki爲關鍵字且關鍵字按順序升序排序,pipi爲指向子樹的結點,則指針pipi所指向子樹中的全部結點的關鍵字均處於[ki,ki+1)[ki,ki+1)範圍內 —— 最左子樹有下限,最右子樹無上限

  • 通常在數據庫系統或文件系統中使用的B+Tree結構都在經典B+Tree的基礎上進行了優化,增長了順序訪問指針。 
    優化

    在B+Tree的每一個葉子節點增長一個指向相鄰葉子節點的指針,就造成了帶有順序訪問指針的B+Tree。作這個優化的目的是爲了提升區間訪問的性能,例如上圖中若是要查詢key爲從18到49的全部數據記錄,當找到18後,只需順着節點和指針順序遍歷就能夠一次性訪問到全部數據節點,極大提到了區間查詢效率。atom

B-Tree和B+Tree的主要區別

  • B-Tree和B+Tree的主要區別: 
    1. B+Tree中每一個結點內的關鍵子個數與指針個數相同;而B-Tree中的關鍵字個數比指針個數少1。
    2. B+Tree中每一個內節點不存儲data(data只存儲在葉子結點),只存儲key;而B-Tree中每一個結點都存儲data。
    3. B+Tree中的查找都結束於葉子結點;而B-Tree中的查找既可能結束於葉子結點,也可結束於內結點。

B+Tree更適合作外部索引

  • 爲何B+Tree更適合作外部索引?

    1. 數據庫系統一般將一個節點的大小設爲一個頁,這樣每一個節點只須要一次I/O就能夠徹底載入 —— 所以磁盤IO次數和樹的高度成正比。

      B-Tree中一次檢索最多須要h1h−1次I/O(根節點常駐內存),即磁盤IO的時間複雜度爲θ(h)=θ(logdN)θ(h)=θ(logd⁡N)。

    2. B-Tree中每一個內結點都既存關鍵字也存數據,而B+Tree中每一個內結點只存關鍵字,所以每一個內結點的關鍵字個數以下所示,從而B+Tree相對於B-Tree的高度更小,所需的磁盤IO次數更少

      • B-Treedd = pagesizepagesize /(keysize+datasize+pointsize)(keysize+datasize+pointsize)
      • B+Treedd = pagesizepagesize /(keysize+pointsize)(keysize+pointsize)

MySQL索引實現

  • 在MySQL中,不一樣存儲引擎對索引的實現方式是不一樣的。

MyISAM索引實現

  • MyISAM引擎使用B+Tree做爲索引結構,葉節點的data域存放的是數據記錄的地址。下圖爲主索引的結構圖: 

  • 在MyISAM中,主索引和輔助索引在結構上沒有任何區別,只是主索引要求key是惟一的,而輔助索引的key能夠重複。 

InnoDB索引實現

  • InnoDB引擎使用B+Tree做爲索引結構,主索引的葉節點的data域存放的是數據記錄自己。 

  • 在InnoDB中,輔助索引的葉結點的data域存放的是對應的主鍵值,以後在主索引結構中繼續查找對應的數據記錄。 

聚類索引和非聚類索引

  • 聚類索引聚類索引是指數據的物理順序與鍵值的邏輯順序相同。

    一個表只能有一個彙集索引,由於一個表的物理順序只有一種狀況,因此對應的聚類索引只能有一個。若是某索引不是彙集索引,則表中的行物理順序與索引順序不匹配 —— InnoDB中的主索引就是聚類索引,由於數據內容存於該索引結構葉子結點的data域中

  • 非聚類索引非聚類索引是數據的物理順序與鍵值的邏輯順序不一樣。例如MyISAM的索引以及InnoDB的輔助索引,由於這些索引結構的葉子結點的data域中實際存儲的是指向數據內容的指針或主鍵值。

相關文章
相關標籤/搜索