您的位置:首页 > 数据库 > MySQL

MySQL Hash Index

2018-02-09 23:45 806 查看
一、什么是Hash Index

哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的査询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

在My SQL中,只有Memory引擎显式支持哈希索引。这也是Memory引擎表的默认索 引类型,Memory引擎同时也支持B-Tree索引。值得一提的是,Memory引擎是支持非 唯一哈希索引的,这在数据库世界里面是比较与众不同的。如果多个列的哈希值相同, 索引会以链表的方式存放多个记录指针到同一个哈希条目中。

它的原理如下:

建立一张Memory存储引擎的表(t_memory),同时在C1列上创建一个Hash 索引

CREATE TABLE
t_memory
(

c1
char(11) DEFAULT NULL,

KEY
idx_c1
(
c1
) USING HASH

) ENGINE=MEMORY DEFAULT CHARSET=utf8;

表里有三条数据,分别是

'AAAA'

'AABB'

'BBBB'


假设MySQL的哈希函数为f_hash(),它返回下列数据:

f_hash(‘AAAA’)=’2323’

f_hash(‘AABB’)=’7437’

f_hash(‘BBBB’)=’2458’

那么索引idx_c1存储的结构如下:

槽(Slot) 值(Value)

2323 指向第1行的指针

2458 指向第3行的指针

7437 指向第2行的指针

当查询条件为C1 = ‘???’ 时,MySQL直接将值使用f_hash()函数计算出Slot值,然后根据Slot值直接找到指针,再去读取整一行数据,这样就可以避开B+Tree索引繁琐的节点查找。

二、InnoDB和MyISAM到底能不能建立Hash Index

先给出答案:不能,但是你建立索引的时候使用USING HASH 关键字,也不会报错。

我们来看这个例子,还是仿照刚才的例子,这不过这次我们表的引擎换成innodb:

创建一张innodb引擎的表,在c1列上建立hash index

CREATE TABLE
t_innodb
(

c1
int(11) DEFAULT NULL

) ENGINE=INNODB DEFAULT CHARSET=utf8;



然后在C1上建立一个Hash Index

CREATE INDEX idx_c1 ON t_innodb(c1) USING HASH;



然而并没有报错,然后show create table t_innodb;

发现结果是这样的



那为什么说InnoDB不支持(或者说不能显示支持)Hash Index,咱们用show index from t_innodb,看看索引真实的类型是什么:



实际上它存储还是B+Tree,结果有点小失望,不过不要紧,看下面一节内容

三、InnoDB的Adaptive Hash Index

为解决上面提到的问题,InnoDB 有另一种实现方法:自适应哈希索引(Adaptive Hash Index)。InnoDB 存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引。

我们来翻译下MySQL5.7的官方文档

Based on the observed pattern of searches, MySQL builds a hash index using a prefix of the index key. The prefix of the key can be any length, and it may be that only some of the values in the B-tree appear in the hash index. Hash indexes are built on demand for those pages of the index that are often accessed.

基于MySQL自身对查找关键字的统计,MySQL会使用索引键值的前缀建立一个hash index,索引键值的前缀可以是任意长度,同时该索引可能只包含B-Tree索引的一部分。Hash Index只包含该索引经常被访问的那些页。

If a table fits almost entirely in main memory, a hash index can speed up queries by enabling direct lookup of any element, turning the index value into a sort of pointer. InnoDB has a mechanism that monitors index searches. If InnoDB notices that queries could benefit from building a hash index, it does so automatically.

如果一个表几乎都缓存在内存,那么建立一个hash index可直接加速查询任意一个元素,同时将索引值转换为指针。 InnoDB有一个监视索引搜索的机制。如果InnoDB注意到查询可以从构建哈希索引中受益,那么它会自动完成(Hash Index的建立)。

从上面可以得出结论,InnoDB的Adaptive Hash Index是MySQL查询优化器根据统计信息自行建立,那么满足那些阀值,才会建立Adaptive Hash Index呢,这里附上一篇何登成前辈的博文:http://hedengcheng.com/?p=458

最后说说如何观察InnoDB的Adaptive Hash Index使用情况。

我们可以通过 SHOW ENGINE INNODB STATUS 来查看当前自适应哈希索引的使用状况:从中我们可以看到自适应哈希索引的相关信息:有使用大小、使用情况、每秒使用自适应哈希索引搜索的情况等。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: