Mysql索引原理及各類tree的比較

1、mysql體系結構

2、mysql索引

一、定義

索引是爲了加速對錶中的數據行的檢索而創造的一種分散存儲的數據結構mysql

二、索引的實現

mysql的索引是由存儲引擎來實現,不一樣的存儲引擎實現方式不一樣。sql

三、存放位置

通常是存放在磁盤中數據庫

四、做用

  • 減小掃描的數據行
  • 能夠把隨機IO變成順序IO
  • 能夠幫助咱們在分組、排序等操做時,避免使用臨時表

五、索引結構

咱們都知道mysql的索引使用B樹來實現的,那麼爲何會考慮B樹,不考慮其餘數據結構呢?數據結構

5.1 首先咱們來看普通的二叉樹。

普通的二叉樹不是絕對平衡的,會有一個問題,以下圖:
性能


它有可能會造成一個鏈表,這樣就失去了二叉樹的優點,須要遍歷查找,性能查。

5.2 那麼若是咱們選擇平衡二叉樹呢?以下圖:



平衡二叉樹沒有普通二叉樹可能會造成鏈表的問題,可是它還有其餘的問題。

a、它太深了
  • 這裏的太深是指樹的高度,你們不要想歪了~
  • 若是在數據量很大的狀況下,這棵樹的高度極可能成千上萬,所以它的IO次數也會很頻繁,會嚴重影響性能
b、它過小了
  • 過小指的是每個磁盤塊(節點)保存的數據量過小了
  • 沒有利用好操做磁盤IO的數據交換特性(4K)
  • 沒有利用好磁盤IO的預讀能力(空間局部性原理)

這裏解釋下爲何說沒有利用好。
一、操做系統磁盤IO的數據交換一次默認是4KB大小,可是咱們的節點裏面存儲的數據遠遠小於4KB,即咱們進行了一次IO可是沒有徹底利用此次IO的數據交換大小,形成浪費。
二、操做系統磁盤IO具有預讀能力,是什麼意思呢?好比咱們要讀取一張20KB大小的jpg圖片,咱們第一次讀了4KB的頭內容,操做系統會認爲咱們可能須要接下來的16KB的剩餘內容,因此會一次性把剩餘的內容都傳輸給咱們。mysql索引

5.3 那麼若是咱們選擇B-Trees即多路平衡查找樹呢?以下圖:


這裏我選擇的是一個3路的平衡查找樹。(即一個節點最多能夠有3-1=2個元素)
能夠看出一樣的高度,它比平衡二叉樹存儲的數據多得多,減小了IO次數,同時每次IO獲取的數據也更多,提高了IO效率。

5.4 最後來看下B+Trees即增強版多路平衡查找樹。以下圖:



它有如下幾個特色:

  • 採用閉合區間
  • 非葉子節點不保存數據,只保存關鍵字和子節點的引用
  • 關鍵字對應的數據保存在葉子節點中
  • 葉子節點是順序排列的,而且相鄰的節點具備順序引用的關係
5.5 那麼咱們爲何要採用B+Trees呢?
  • 擁有多路的優點
  • 掃表能力強
  • 磁盤IO能力強
  • 排序能力強
  • 查詢能力更穩定

這裏我解釋下爲何說B+Trees的查詢能力更穩定:
B-Trees可能掃秒到第一層就返回,也可能掃秒到最後一層才返回。可能很快也可能很慢。
B+Trees每次都要掃面到最後一層,所以速度更加穩定。優化

六、B樹在存儲引擎中的實現方式

6.一、Myisam

  • 非聚簇索引,數據和索引分別存儲。
  • 索引文件xx.MYI
  • 數據文件xx.MYD
  • 葉子節點保存的是引用地址而非數據
6.二、InnoDB

  • 聚簇索引,數據和索引保存在一塊兒
  • 文件xx.ibd
  • 在葉子節點保存對應的全部數據
  • 以主鍵索引來組織數據,沒有主鍵的話,會幫咱們隱式建立主鍵索引
  • 輔助索引不存地址,存主鍵,這樣便於維護

七、列的離散性

  • 列的離散性在索引中是一種很重要的指標。
  • 列的離散性 x = count(distinct col) : count(col)
  • 比例越大,離散性越高,選擇性就越好
  • 下面咱們看個例子來理解:
  • name的列的離散性 x1 = 5 : 5 = 1
  • sex的列的離散性 x2 = 2 : 5 = 0.4
  • x1>x2,因此sex的列的離散性低,可選擇性差。
  • 可選擇性差是什麼意思呢?好比有如上100W的數據,如今咱們要查找sex=男的,那麼在索引中咱們可選擇的範圍太大了,由於只有男或者女,查詢效率就很低
  • 在mysql查詢優化器中,若是列的離散性低的話,可能就不走索引,直接全表掃描

八、聯合索引

8.1 創建聯合索引的原則:
  • 常常用的列優先
  • 離散性高的列優先
  • 寬度小的列優先
8.2 適用性:
  • 若是不是最左匹配,則沒法使用聯合索引
  • 範圍查詢以後的不走聯合索引
  • where id = 1 and age > 10 and sex = 女 只有id、age走聯合索引
  • where id > 1 and age = 10 只有id走聯合索引
  • where id = 1 and age = 10 and sex > 女 id、age、sex走聯合索引

九、覆蓋索引

  • 定義:若是查詢的列能夠經過索引節點的關鍵字直接返回,則稱之爲覆蓋索引操作系統

  • 索引名稱: index_name 索引列:name
    覆蓋:select name from user where name= ?
    非覆蓋:select * from user where name= ?3d

  • 覆蓋索引能夠減小數據庫IO操做,不須要回表,而是在子節點就能夠獲取關鍵字進行返回。cdn

十、創建索引的原則

  • 索引不易建多:維護B+Trees成本高,插入、更新、刪除等操做要作不少邏輯判斷
  • 索引列的長度不易過長:會影響B+Trees的路數,進而影響IO效率
相關文章
相關標籤/搜索