1哈希索引原理

哈希索引原理其实就是hash表,搜索时间效率O(1),搜索效率好,也意味着磁盘IO花费少,mysql底层使用的是链式哈希表,结构如下,每一个bucket就是一个个哈希桶,也就是哈希链表的头结点。哈希结构天然的需要耗费空间资源,是一种用空间换时间的做法

2哈希要点:

  • 解决哈希冲突的几种方式
  • 再哈希的参数碰撞因子或者说负载因子

MySQL-hash索引_二级索引

说白了就是用的拉链法去解决的哈希冲突,也正是这个结构造成了哈希索引的一些特性

  • 哈希表没有顺序可言,只能进行等值查询,不支持范围搜索
  • 哈希表不稳定,效率最差可能变为O(n),因为哈希冲突链表可能会变长
  • 天然不能减少磁盘IO,要基于内存
  • 会锁住桶,有可能造成阻塞

3创建哈希索引sql语句如下

create index nameidx on student(name) using hash;

提示一下即使创建的是hash索引,也不一定就是哈希结构,Mysql会自动优化,具体用的是什么索引还是需要看看的,依然有可能使用的还是BTREE索引

show indexes from student;

4自适应哈希索引

自适应哈希索引作用:MySQL Server为避免频繁回表,会使用频繁访问的二级索引项创建哈希索引

假如name是有索引的,我们不断使用如下的方式查询,那就得先访问name的二级索引树,从二级索引树上取出主键uid,然后回表,用这个uid去主键索引树上取得对应的数据

select * from student where name = "zhangsan";

select * from student where name = "gaoyang";

select * from student where name = "linfeng";

...

The hash index is always built based on an existing B-tree index on the table. InnoDB can build a hash index on a prefix of any length if the key defined for the B-tree

InnoDB存储引擎会做如下优化:如果检测到某个二级索引不断被使用,二级索引成为热数据,那么InnoDB会根据在二级索引树上的索引值在构建一个哈希索引来加速搜索(只适用于等值比较)

MySQL-hash索引_搜索_02

图中蓝色的箭头表示不建立哈希索引,搜索二级索引树然后回表的过程

黄色箭头就是直接等值比较搜索哈希表,直接拿到数据地址的过程。使用哈希索引O ( 1 ) O(1)O(1)的时间复杂度就访问到哈希索引name,然后取出data即可(对于InnoDB来说应该是直接取得数据,而不是拿到数据地址后再访问)

注意:hash索引的生成和维护也是耗费性能的,并不能绝对的在任何场景下提高对二级索引的搜索效率,我们可以查看相关参数指标,如果自适应哈希索引可以提高效率,那我们使用它,否则我们就关闭它。

自适应哈希索引创建后,就会在等值查询的时候直接查询哈希索引,哈希索引上有数据的地址,这样就省下了辅助索引跟主键索引的搜索时间

其实创建哈希索引也是比较消耗资源的,这里有些衡量参数,要根据衡量参数决定是否打开或者关闭自适应哈希索引,mysql官方文档里面也讲了这个,上面不讲人话部分就是对何时创建自适应哈希索引以及如何禁用哈希索引、哈希索引锁的说明。

查看自适应哈希索引是否开启的命令

show variables like 'innodb_adaptive_hash_index';

查看自适应哈希分区(或者说桶)

show variables like 'innodb_adaptive_hash_index_parts';

两个比较重要的信息要注意,查看命令如下

show engine innodb status\G

能看到RW-latch等待的线程数量,自适应哈希索引默认分配了8个分区,同一个分区等待的线程数量过多

走自适应哈希索引搜索的频率和二级索引树搜索的频率