MySQL 之 InnoDB

1.索引數據結構選擇

索引是爲了提高數據查詢的效率,提高讀寫的數據結構有很多,常見的數據結構有:哈希表,有序數組和平衡二叉查找數。而MySQL的InnoDB爲什麼要選擇B+樹呢?

  • 哈希表:插入單個數據時間複雜度爲O(1),查找和刪除時間複雜度跟鏈表的長度成正比,鏈表長爲k時時間複雜度爲O(k)。哈希表中數據是無序的不支持範圍查找,適合於等值查找。
  • 有序數組: 通過二分法查找數據時間複雜度爲O(logN),等值和範圍查詢效率很高,但是新增和刪除每次都要移動大量的數據,時間複雜度就變爲了O(n),成本太高。有序數組適合於靜態數據索引查找。
  • 平衡二叉查找樹: 平衡二叉查找樹的查詢複雜度爲O(logN),插入和刪除時間複雜度爲O(logN)效率也很高,中序遍歷後也支持範圍查找。
1.1.InnoDB爲什麼選擇B+樹

既然平衡二叉樹這麼高效了爲什麼還要用B+樹作爲MySQL索引的存儲數據結構了。當有數據有100W時,樹高20,一次查詢就需要訪問20個數據塊,從磁盤隨機讀一個數據塊大概需要10ms左右,而內存中讀取數據是納秒級別,在磁盤上讀取20個數據塊所消耗的時間就不能接受了。能不能減少數據塊次數的讀取就成爲關鍵了。

這時候N叉樹就出現了,當N=100時1億個數據樹高就只有3了,查找一次數據最多隻有3次磁盤操作,操作磁盤次數減少,查找效率也就提高了。B+樹其實就是一個父節點有N個子節點既然N叉樹的一種。

1.2.N的取值

在操作系統中讀取磁盤中的數據是按頁讀取,如果讀取的數據小大超過一頁就會出發多次IO操作。在選擇N大小時,儘量讓每個節點的大小等於一個頁的大小。影響N的大小是由頁大小和索引數據大小所決定,如一個也大小爲4KB,索引數據爲整型時,整型數據大小爲4個字節,則N大小爲1024。

2.InnoDB常見索引

InnoDB中的表都是根據主鍵順序按索引的形式存儲,這種存儲方式的表稱爲索引組織表,InnoDB是使用的B+樹作爲索引模型,其數據都存放在葉子節點,父節點存儲着索引值。

  • 主鍵索引
    主鍵索引是將正行數據都放在葉子節點,MySql中主鍵索引也稱聚簇索引

  • 非主鍵索引
    非主鍵索引的葉子節點存儲的是主鍵的值,非主鍵索引也被稱之爲二級索引,其中常見的非主鍵索引包括普通索引覆蓋索引

2.1.主鍵索引與非主鍵索引的區別
  • 主鍵索引葉子節點存儲整行數據,非主鍵索引葉子節點存儲主鍵值
  • 主鍵索引只搜索主鍵的B+索引樹,只需要搜索一次。非主鍵索引先搜索自己的索引樹得到主鍵之後再去回查主鍵索引,這個過程叫做回表,非主鍵索引需要進行兩次搜索。
2.2.主鍵索引使用場景

B+樹作爲一個動態數據結構的樹爲了維護索引的有序性,在插入或刪除節點時都要做一些必要的維護,當數據頁寫滿時需要頁分裂,當數據頁利用率不足時需要頁合併。

2.2.1.主鍵自增長

爲什麼主鍵要定義爲自增長,當主鍵定義爲自增長時每次插入一條數據,新增數據ID爲系統中最大的ID+1,這樣數據就能以遞增的方式插入,每次新增都是增加操作,則不會造成葉子節點頁分裂的場景。

當業務字段作爲主鍵時,業務字段不能保證有序數據隨機寫入,從而會造成頁分頁。

主鍵數據長度越小,普通索引所佔空間就越小,主鍵自增長主鍵的數據類型爲整型只佔4個字節

2.2.2.業務字段作爲主鍵

業務字段保證數據唯一
只存在一個索引

典型的場景就是KV場景

2.3.非主鍵索引使用場景
2.3.1.覆蓋索引

聯合索引是多個字段組成的索引,當查詢的字段都在索引列中時就可以直接返回,不需要再次回表查詢,從而減少一次查詢,這個索引稱之爲覆蓋索引

覆蓋索引可以減少樹的搜索次數提高性能,可以作爲一種優化方式,選擇場景爲:

  • 當要查詢的字段都可以作爲索引,則使用覆蓋索引
  • 如果通過調整索引字段順序,可以少維護一個索引,則優先採用這個順序作爲聯合索引的順序,聯合索引遵循最左匹配原則。
2.3.2.索引下推

當一個表數據爲:

ID name age
id1 張三 10
id2 張四 20
id3 張五 10
id4 李六 30

name和age爲聯合索引。
查詢語句爲:

select * from user where name like '張%' and age=10;

MySQL在5.6之後引入索引下推,上面SQL執行流程爲:

  1. 聯合索引根據name查詢出id1,id2,id3三條記錄
  2. age=10條件直接在聯合索引上錄刷選處理只發送id1,id3兩條記錄。
  3. 將id1,id3發送到主鍵索引查詢

根據上述流程來看,索引下推在查詢第一顆索引樹時就做了過濾減少回表的數據量查詢。也可以作爲一種優化方式。

參考文獻

  • 極客時間《MySQL實戰45講》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章