mysql的索引是在存儲引擎層實現的與服務層無關。這也就決定了不同的存儲引擎是有不同的實現的。
mysql支持的索引類型
b-tree索引
- 以b+tree的結果存儲數據
- 能夠加快數據的查詢速度,通常索引大小遠小於數據本身
- 更適合範圍查找
使用場景:
- 全值匹配的查詢:order_sn = '2342342346763'
- 匹配最左前綴的查詢
- 匹配列前綴的查詢:order_sn like '234234%'
- 匹配範圍的查詢:order_sn > '2342342346763' and order_sn < '1232346763'
- 精確匹配左前列並範圍匹配另外一列
- 只訪問索引的查詢
使用限制:
- 如果不是按照索引最左列開始查找,則無法使用索引
- 使用索引時不能跳過索引中的列
- not in 和<> 操作無法使用索引
- 如果查詢中某個列有範圍查詢,則其右邊所有的列都無法適用索引
hash索引
- hash索引是基於hash表實現的,只有查詢條件精確匹配hash索引中的所有列時,才能夠使用
- 對於hash索引中的所有列,存儲引擎都會爲每一行計算一個hash值,hash索引存儲的就是hash值
使用限制:
- hash索引必須進行二次查找,通過hash值找到row,再讀取row
- hash索引無法進行排序
- hash索引不支持部分索引和範圍查找
- 可能存在hash衝突
索引是不是越多越好?
- 索引會增加寫操作的成本
- 太多的索引會增加查詢優化器的選擇時間
索引優化策略
- 索引列上不能使用表達式或者函數
- 前綴索引和索引的選擇性
- 聯合索引 :經常會使用到的列優先,選擇性高的列優先,寬度小的列優先
- 覆蓋索引:可以優化緩存較少磁盤IO,變隨機IO爲順序IO,覆蓋索引必須要存儲索引的列,而哈希索引、空間索引和全文索引等都不存儲索引列的值,所以MySQL只能使用B-Tree索引做覆蓋索引
不能使用覆蓋索引的情況?
- 存儲引擎不支持
- 查詢中使用了太多的列
- 使用了雙%號的like查詢
- 使用索引掃描優化排序
- 索引的列順序和order by子句的順序完全一致
- 索引中所有列的方向(升序,降序)和order by 子句完全一致
- order by 中的字段全部在關聯表中的第一張表中
- 使用索引減少鎖的時間
刪除重複和冗餘的索引
pt-duplicate-keyi-checker h = 127.0.0.1
查找未被使用過的索引