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
查找未被使用过的索引