Mysql 索引原理及優化


Mysql 索引原理及優化

什么是索引

為什么需要索引?

  • 索引是數據表種一個或者多個列進行排序的數據結構
  • 索引能夠大幅提升檢索速度
  • 創建、更新索引本身也會耗費空間和時間
查找結構進化史
  • 線性查找:一個個找;實現簡單;太慢
  • 二分查找:有序;簡單;要求是有序的,插入特別慢
  • HASH查找:查詢快;占用空間;不太適合存儲大規模數據
  • 二叉查找樹:插入和查詢很快(log(n));無法存大規模數據,復雜度退化
  • 平衡樹:解決 BST 退化問題,樹是平衡的;節點非常多的時候,依然樹高很高
  • 多路查找樹:一個父親多個孩子節點(度);節點過多樹高不會特別深
  • 多路平衡查找樹:B-Tree

關於這些查找結果的演示推薦:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

這個網站關於數據結構的演示很直觀,我們可以通過其中的動畫來學習。

比如二叉查找樹退化問題:

可以明顯看到,由於我們輸入的數字是順序增長的,二叉查找樹變成了單邊增長的線性結構,這就是復雜度退化。

平衡樹(AVL)則沒有這個問題:

什么是 B-Tree?
  • 多路平衡查找樹(每個節點最多 m(m>=2) 個孩子,稱為 m 階或者度)
  • 葉節點具有相同的深度
  • 節點的數據 key 從左到右是遞增的

演示

B+Tree
  • Mysql 實際使用的 B+Tree 作為索引的數據結構
  • 只在葉子節點帶有指向記錄的指針(For what?可以增加樹的度)
  • 葉子節點通過指針相連(For what?實現范圍查詢)

Mysql 創建索引類型
  • 普通類型(CREATE INDEX)
  • 唯一索引,索引列的值必須唯一(CREATE UNIQUE INDEX)
  • 多列索引
  • 主鍵索引(PRIMARY KEY),一個表只能有一個
  • 全文索引(FULLTEXT INDEX),InnoDB 不支持
什么時候創建索引
  • 經常用作查詢條件的字段
  • 經常用作表連接的字段
  • 經常出現在 order by,group by 之后的字段
創建索引有哪些需要注意的?

最佳實踐

  • 非空字段 NOT NULL,Mysql 很難對空值作查詢優化
  • 區分度高,離散度大,作為索引的字段值盡量不要有大量相同值
  • 索引的長度不要太長(比較耗費時間)
索引什么時候失效?

模糊匹配、類型隱轉、最左匹配

  • 以 % 開頭的 LIKE 語法,模糊搜索
  • 出現隱式類型轉換(在 Python 這種動態語言查詢中需要注意)
  • 沒有滿足最左前綴原則
什么是聚集索引和非聚集索引?
  • 聚集還是非聚集指的是 B+Tree 葉節點存的是指針還是數據記錄
  • MyISAM 索引和數據分離,使用的是非聚集索引
  • InnoDB 數據文件就是索引文件,主鍵索引就是聚集索引

對比如下

聚集索引

非聚集索引

區別是在 B+Tree 的葉節點存儲數據還是指針
MyISAM 索引是非聚集的,InnoDB 主鍵索引是聚集索引

輔助索引

還有一個輔助索引,我們也可以了解下。

輔助索引

如何排查慢查詢

慢查詢通常是缺少索引,索引不合理或者業務代碼實現所致

  • slow_query_log_file 開啟並且查詢慢查詢日志
  • 通過 explain 排查索引問題
  • 調整數據修改索引;業務代碼層限制不合理訪問


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM