MySql乾貨分享之索引

qbhy發表於2020-09-25

MySQL是一個關係型資料庫管理系統,由瑞典MySQL AB 公司開發,屬於 Oracle 旗下產品。MySQL 是最流行的關係型資料庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關聯式資料庫管理系統) 應用軟體之一。

今天我們就來聊聊MySQL的索引。儘管MySQL有許多優點,但是在海量資料的情況下,效能方面的表現還是會讓人捉急,這時候就輪到MySQL的索引出場了。我會以丟擲問題然後解決問題的方式來進行本次分享。比如:什麼是索引?索引可以做什麼?為什麼使用索引可以提高效率?MySQL支援哪些索引型別?什麼情況下應不建或少建索引?什麼是聯合索引?為什麼說B+比B樹更適合實際應用中作業系統的檔案索引和資料庫索引?

官方解釋:索引(Index)是幫助MySQL高效獲取資料的資料結構。

通俗理解:索引是一種特殊的檔案(InnoDB 資料表上的索引是表空間的一個組成部分),它們包含著對資料表裡所有記錄的引用指標。

首先,索引不是萬能的,索引可以加快資料檢索操作,但會使資料修改操作變慢。每次修改資料記錄,索引就必須重新整理一次。為了在某種程度上彌補這一缺陷,許多 SQL 命令都有一個 DELAY_KEY_WRITE 項。這個選項的作用是暫時制止 MySQL 在該命令每插入一條新記錄和每修改一條現有之後立刻對索引進行重新整理,對索引的重新整理將等到全部記錄插入/修改完畢之後再進行。在需要把許多新記錄插入某個資料表的場合,DELAY_KEY_WRITE 選項的作用將非常明顯。

  • 資料索引的儲存是有序的
  • 在有序的情況下,透過索引查詢一個資料是無需遍歷索引記錄的
  • 極端情況下,資料索引的查詢效率為二分法查詢效率,趨近於 log2(N)

我們這裡說的索引型別並不是指“主鍵索引”、“外來鍵索引”這些,而是索引底層的資料結構。MySQL的索引資料結構支援以下兩種:

  • B-Tree 索引。B+樹是一個平衡的多叉樹,從根節點到每個葉子節點的高度差值不超過1,而且同層級的節點間有指標相互連結,是有序的,如下圖:
    MySql乾貨分享之索引
  • Hash 索引。雜湊索引就是採用一定的雜湊演算法,把鍵值換算成新的雜湊值,檢索時不需要類似B+樹那樣從根節點到葉子節點逐級查詢,只需一次雜湊演算法即可,是無序的,如下圖所示:
    MySql乾貨分享之索引
    • 雜湊索引的優勢:等值查詢,雜湊索引具有絕對優勢(前提是:沒有大量重複鍵值,如果大量重複鍵值時,雜湊索引的效率很低,因為存在所謂的雜湊碰撞問題。)
    • 雜湊索引不適用的情況:
      • 不支援範圍查詢
      • 不支援索引完成排序
      • 不支援聯合索引的最左字首匹配規則

我們都知道什麼時候應該使用索引,那麼,什麼時候不應該使用索引呢?我們上面說到,索引並不是萬能的,所以,索引肯定也有不適用的場景。以下幾個場景的時候,我們應該儘量不建或者說少建索引:

  • 表記錄太少。
  • 經常插入、刪除、修改的表。
  • 資料重複且分佈平均的表欄位,假如一個表有10萬行記錄,有一個欄位A只有T和F兩種值,且每個值的分佈機率大約為50%,那麼對這種表A欄位建索引一般不會提高資料庫的查詢速度。
  • 經常和主欄位一塊查詢但主欄位索引值比較多的表欄位。
  • 聯合索引是兩個或更多個列上的索引。
    對於聯合索引,MySQL支援從左到右的使用索引中的欄位,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c),可以支援a 、 a,b 、 a,b,c 這3種組合進行查詢,但不支援 b,c進行查詢,當最左側欄位是常量引用時,索引就十分有效。
  • 利用索引中的附加列,您可以縮小搜尋的範圍,但使用一個具有兩列的索引不同於使用兩個單獨的索引。
  • 複合索引的結構與電話簿類似,人名由姓和名構成,電話簿首先按姓氏對進行排序,然後按名字對有相同姓氏的人進行排序。如果您知道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不知道姓,電話簿將沒有用處。
  • B+的磁碟讀寫代價更低。B+的內部結點並沒有指向關鍵字具體資訊的指標,因此其內部結點相對B樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入記憶體中的需要查詢的關鍵字也就越多。相對來說IO讀寫次數也就降低了。
  • B+-tree的查詢效率更加穩定。由於非終結點並不是最終指向檔案內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查詢必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個資料的查詢效率相當。

看到這裡,你應該已經把MySQL的索引知識都過了個大概,希望本文能幫到你,happy hacking。​接下來聽首聽首歌放鬆一下吧。
真的愛你 BEYOND - BEYOND

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章