三、MySQL 索引优化

索引优化


一、索引类型

1. B-Tree 索引

特点

  • a).B-Tree 索引能够加快数的查询速度
  • b).B-Tree 索引以B+树的结构存储数据:
  • 每一个叶子节点到根部的距离相同
  • InnoDB引擎指针指向被索引的数据而不是主键,MyISAM引擎指针指向物理地址
  • 顺序存储,适合进行范围查找

何时命中

  • 全值匹配的查询
    order_no = ‘20190825102500001’
  • 匹配最左前缀的查询
    – 创建如下索引
    KEY index (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’ 时可命中
  • 精确匹配左前列并范围匹配另外一列
    – 创建如下索引
    KEY index (order_no,order_date) USING BTREE
    当 where order_no = ‘20190825102500001’ and order_date > ‘20190825’ 时依然可以命中索引
  • 只访问索引的查询

使用限制

  • 如果不是按照索引最左列开始查找,则无法使用索引
  • 使用索引时不能跳过索引中的列
    – 创建如下索引
    KEY index (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 查询优化器会根据索引的统计信息和查询条件来选择合适的索引。而同一个查询有很多的索引可以使用时,会增加查询优化器分析的时间,从而影响查询效率
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章