索引優化
一、索引類型
1. B-Tree 索引
特點
- a).B-Tree 索引能夠加快數的查詢速度
- b).B-Tree 索引以B+樹的結構存儲數據:
- 每一個葉子節點到根部的距離相同
- InnoDB引擎指針指向被索引的數據而不是主鍵,MyISAM引擎指針指向物理地址
- 順序存儲,適合進行範圍查找
何時命中
- 全值匹配的查詢
order_no = ‘20190825102500001’ - 匹配最左前綴的查詢
– 創建如下索引
KEYindex
(order_no
,order_date
) USING BTREE
當 where order_no = ‘20190825102500001’ 時依然可以命中索引
當 where order_date = ‘20190805’ 時無法命中索引 - 匹配列前綴查詢
當 where order_no like ‘20190825%’ 時可命中
當 where order_no like ‘%82500001’ 時不可命中 - 匹配範圍值的查詢
當 where order_no > ‘20190825102500001’ 時可命中 - 精確匹配左前列並範圍匹配另外一列
– 創建如下索引
KEYindex
(order_no
,order_date
) USING BTREE
當 where order_no = ‘20190825102500001’ and order_date > ‘20190825’ 時依然可以命中索引 - 只訪問索引的查詢
使用限制
- 如果不是按照索引最左列開始查找,則無法使用索引
- 使用索引時不能跳過索引中的列
– 創建如下索引
KEYindex
(order_date
,‘user_name’,‘mobile’) USING BTREE
當 where order_date = ‘20190825’ and mobile = ‘15900001111’ 時無法命中索引,即不能跳過 user_name 列 - not in 和 <> 操作無法使用索引
- 如果查詢中有某個索引列的範圍查詢,則其右邊所有列都無法使用索引
2. Hash 索引
特點
- Hash 索引是基於 Hash 表來實現的,只有查詢條件精確匹配 Hash 索引中所有列時,才能夠命中索引
- 對於 Hash 索引中所有列,存儲引擎都會爲每一行計算一個 Hash 碼, Hash 索引中存儲的就是 Hash 碼,Hash 碼通常會比較小,存在 Hash 衝突
- Hash 索引中存儲 鍵、值、Hash碼、對應行的指針
何時命中
- 僅當查詢條件全部匹配是才命中,因此不適合範圍查找,只適合等值查詢
使用限制
- Hash 索引必須進行二次查找,因爲無論是 Memory 引擎還是 InnoDB 引擎 對頻繁訪問的行都存儲在內存當中了,而內存的訪問速度很快,所以基本可以忽略
- Hash 索引無法用於排序
- Hash 索引不支持部分索引查找也不支持範圍查詢
- 存在 Hash 衝突,適合在重複概率小的列建立 Hash 索引,比如【證件號碼】,而類似【性別】就不適合
3. 索引好處
- 索引大大減少了存儲引擎需要掃描的數據量
- 索引可以幫助我們進行排序以避免使用臨時表,避免IO消耗以提高處理能力
- 索引可以把隨機 IO 變爲順序 IO
4. 索引不是越多越好
- 索引會增加寫操作的成本:insert、update、delete 時需要維護索引,InnoDB 引入了插入緩存解決該問題
- 太多的索引會增加傳優化器的選擇時間:MySQL 查詢優化器會根據索引的統計信息和查詢條件來選擇合適的索引。而同一個查詢有很多的索引可以使用時,會增加查詢優化器分析的時間,從而影響查詢效率