Mysql 索引原理及優化
什麼是索引
爲何須要索引?html
- 索引是數據表種一個或者多個列進行排序的數據結構
- 索引可以大幅提高檢索速度
- 建立、更新索引自己也會耗費空間和時間
查找結構進化史
- 線性查找:一個個找;實現簡單;太慢
- 二分查找:有序;簡單;要求是有序的,插入特別慢
- HASH查找:查詢快;佔用空間;不太適合存儲大規模數據
- 二叉查找樹:插入和查詢很快(log(n));沒法存大規模數據,複雜度退化
- 平衡樹:解決 BST 退化問題,樹是平衡的;節點很是多的時候,依然樹高很高
- 多路查找樹:一個父親多個孩子節點(度);節點過多樹高不會特別深
- 多路平衡查找樹:B-Tree
關於這些查找結果的演示推薦:https://www.cs.usfca.edu/~galles/visualization/Algorithms.htmlsql
這個網站關於數據結構的演示很直觀,咱們能夠經過其中的動畫來學習。數據結構
好比二叉查找樹退化問題:學習
![](http://static.javashuo.com/static/loading.gif)
能夠明顯看到,因爲咱們輸入的數字是順序增加的,二叉查找樹變成了單邊增加的線性結構,這就是複雜度退化。優化
平衡樹(AVL)則沒有這個問題:動畫
![](http://static.javashuo.com/static/loading.gif)
什麼是 B-Tree?
- 多路平衡查找樹(每一個節點最多 m(m>=2) 個孩子,稱爲 m 階或者度)
- 葉節點具備相同的深度
- 節點的數據 key 從左到右是遞增的
![](http://static.javashuo.com/static/loading.gif)
演示網站
![](http://static.javashuo.com/static/loading.gif)
B+Tree
- Mysql 實際使用的 B+Tree 做爲索引的數據結構
- 只在葉子節點帶有指向記錄的指針(For what?能夠增長樹的度)
- 葉子節點經過指針相連(For what?實現範圍查詢)
![](http://static.javashuo.com/static/loading.gif)
Mysql 建立索引類型
- 普通類型(CREATE INDEX)
- 惟一索引,索引列的值必須惟一(CREATE UNIQUE INDEX)
- 多列索引
- 主鍵索引(PRIMARY KEY),一個表只能有一個
- 全文索引(FULLTEXT INDEX),InnoDB 不支持
何時建立索引
- 常常用做查詢條件的字段
- 常常用做錶鏈接的字段
- 常常出如今 order by,group by 以後的字段
建立索引有哪些須要注意的?
最佳實踐spa
- 非空字段 NOT NULL,Mysql 很難對空值做查詢優化
- 區分度高,離散度大,做爲索引的字段值儘可能不要有大量相同值
- 索引的長度不要太長(比較耗費時間)
索引何時失效?
模糊匹配、類型隱轉、最左匹配指針
- 以 % 開頭的 LIKE 語法,模糊搜索
- 出現隱式類型轉換(在 Python 這種動態語言查詢中須要注意)
- 沒有知足最左前綴原則
什麼是彙集索引和非彙集索引?
- 彙集仍是非彙集指的是 B+Tree 葉節點存的是指針仍是數據記錄
- MyISAM 索引和數據分離,使用的是非彙集索引
- InnoDB 數據文件就是索引文件,主鍵索引就是彙集索引
對好比下日誌
![彙集索引](http://static.javashuo.com/static/loading.gif)
![非彙集索引](http://static.javashuo.com/static/loading.gif)
區別是在 B+Tree 的葉節點存儲數據仍是指針 MyISAM 索引是非彙集的,InnoDB 主鍵索引是彙集索引
輔助索引
還有一個輔助索引,咱們也能夠了解下。
![輔助索引](http://static.javashuo.com/static/loading.gif)
如何排查慢查詢
慢查詢一般是缺乏索引,索引不合理或者業務代碼實現所致
slow_query_log_file
開啓而且查詢慢查詢日誌
- 經過
explain
排查索引問題
- 調整數據修改索引;業務代碼層限制不合理訪問