天天看點

MySQL索引,快速記憶法

作者:架構師之道

面試的時候,面試官總喜歡問一些關于MySQL索引的問題,但是如果單純的記憶,還是有難度的;今天了不起把MySQL索引的知識點進行彙總,友善大家快速記憶MySQL索引的相關知識點。趕快收藏此文章吧!

索引結構:B+樹

索引其實是一種資料結構

注意B+樹是MySQL,索引預設的結構;一張表至少有一個索引(主鍵索引),是可以有多個索引的

MySQL中的B+Tree

  1. 非葉子節點也叫内部節點,隻存儲 健值(主鍵的值) + 指針(存儲子節點的位址資訊)
  2. 主鍵索引:健值(主鍵的值) + 指針(存儲子節點的位址資訊)
  3. 非主鍵索引:非主鍵列的值 + 指向下一個節點的指針(存儲子節點的位址資訊)
  4. 所有的資料都存在葉子節點中;
  5. 同時葉子節點上還存有一個指向相鄰葉子節點的指針
  6. 如果是聚簇索引(主鍵索引),葉子節點存儲的是實際資料
  7. 如果是非聚簇索引,則儲存的是聚簇索引的索引key,也就是主鍵索引的值;查詢非聚簇索引會有一個回表操作
  8. B+Tree的每個葉子節點增加了一個指向相鄰葉子節點的指針,它的最後一個資料會指向下一個葉子節點的第一個資料,形成了一個有序連結清單的結構。

為什麼B+ 樹比B 樹更适合作為索引?

  1. B+ 樹的磁盤讀寫代價更低 B+ 樹的資料都集中在葉子節點,分支節點 隻負責指針(索引);B 樹的分支節點既有指針也有資料 。這将導緻B+ 樹的層高會小于B 樹的層高,也就是說B+ 樹平均的Io次數會小于B 樹。
  2. B+ 樹的查詢效率更加穩定 B+ 樹的資料都存放在葉子節點,故任何關鍵字的查找必須走一條從根節點到葉子節點的路徑。所有關鍵字的查詢路徑相同,每個資料查詢效率相當。
  3. B+樹更便于周遊 由于B+樹的資料都存儲在葉子結點中,分支結點均為索引,周遊隻需要掃描一遍葉子節點即可;B樹因為其分支結點同樣存儲着資料,要找到具體的資料,需要進行一次中序周遊按序來搜尋。
  4. B+樹更擅長範圍查詢 B+樹葉子節點存放資料,資料是按順序放置的雙向連結清單。B樹範圍查詢隻能中序周遊。
  5. B+ 樹占用記憶體空間小 B+ 樹索引節點沒有資料,比較小。在記憶體有限的情況下,相比于B樹索引可以加載更多B+ 樹索引。

MyISAM與InnoDB 的差別

  1. InnoDB支援事務,MyISAM不支援
  2. InnoDB支援外鍵,而MyISAM不支援
  3. InnoDB是聚集索引,資料和索引存到同一個檔案裡;MyISAM是非聚集索引,資料和索引不在同一個檔案裡;都是使用B+Tree作為索引結構
  4. InnoDB不儲存表的具體行數,執行select count(*) from table時需要全表掃描。而MyISAM用一個變量儲存了整個表的行數,執行上述語句時隻需要讀出該變量即可,速度很快(注意不能加有任何WHERE條件)因為InnoDB的事務特性,在同一時刻表中的行數對于不同的事務而言是不一樣的,是以count統計會計算對于目前事務而言可以統計到的行數,而不是将總行數儲存起來友善快速查詢。InnoDB會嘗試周遊一個盡可能小的索引除非優化器提示使用别的索引。如果二級索引不存在,InnoDB還會嘗試去周遊其他聚簇索引。如果索引并沒有完全處于InnoDB維護的緩沖區(Buffer Pool)中,count操作會比較費時。可以建立一個記錄總行數的表并讓你的程式在INSERT/DELETE時更新對應的資料。和上面提到的問題一樣,如果此時存在多個事務的話這種方案也不太好用。如果得到大緻的行數值已經足夠滿足需求可以嘗試SHOW TABLE STATUS
  5. 那麼為什麼InnoDB沒有了這個變量呢?
  6. InnoDB支援表、行(預設)級鎖,而MyISAM僅支援表級鎖
  7. InnoDB表必須有唯一索引(如主鍵)(使用者沒有指定的話會自己找/生産一個隐藏列Row_id來充當預設主鍵),而Myisam可以沒有主鍵
  8. Innodb存儲檔案有frm、ibd,而Myisam是frm、MYD、MYI
  9. Innodb:frm是表定義檔案,ibd是資料檔案
  10. Myisam:frm是表定義檔案,myd是資料檔案,myi是索引檔案

索引失效的場景

  1. 對索引列使用了函數、表達式或運算符:當查詢條件中使用了函數、表達式或運算符時,MySQL就無法使用該列的索引,因為它需要對每行資料進行計算,而不是直接查找索引。
  2. 查詢條件中使用了不等于操作符(<>、!=)、NOT NULL, NOT IN 等
  3. 模糊查詢:當查詢條件中使用了LIKE、%或_等模糊比對符号時,MySQL無法使用索引進行快速定位。
  4. OR條件:當查詢條件中包含多個OR條件時,MySQL無法使用索引進行快速定位。
  5. 範圍查詢:當查詢條件中使用了BETWEEN、<、>、<=、>=等操作符時,MySQL隻能使用索引中的一部分資料,需要讀取更多的資料進行過濾,降低了查詢效率。
  6. 資料類型不比對,需要隐式轉換類型
  7. 對索引列進行排序,因為它需要将資料按照指定的順序進行排序
  8. 複合索引,如果不使用前列,後續列也将無法使用

小結

正确的使用索引,能夠顯著提高資料庫的查詢效率。本文彙總了MySQL索引的常用知識點,幫助大家快速記憶,快快收藏吧。

來源:https://mp.weixin.qq.com/s?__biz=Mzg4MjYyOTgwNw==&mid=2247496695&idx=

繼續閱讀