只有Memory引擎支持哈希索引(不讨论NDB集群支持唯一哈希索引的情况)
哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效。
存储引擎会根据所有的索引计算出一个哈希码
哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行额指针。
因为索引只是只需要存储对应的哈希值,所以索引的结构十分紧凑,使得哈希表查询非常快。
哈希表有一下限制:
哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中值来避免行读取
哈希索引不是按照索引顺序存储的,因此也无法用于排序
哈希索引不支持部分索引匹配,因为哈希索引是根据全部索引列计算的哈希码
哈希索引只支持等值比较查询,=、in、<=>,不支持范围查询例如where a>100
访问哈希索引非常快,除非是哈希冲突,当出现哈希冲突时,存储引擎必须遍历链表中所有的行指针,逐行比较,直到找到符合条件的行
验证“哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效”
举例:
CREATE TABLE `white_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`teacherEmail` varchar(30) DEFAULT NULL,
`whiteFlag` int(1) DEFAULT '0',
`creationTime` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `PK_INDEX` (`teacherEmail`,`whiteFlag`) USING HASH
) ENGINE=MEMORY AUTO_INCREMENT=64 DEFAULT CHARSET=utf8;
针对以下四种情况:只有前两种可以使用到hash索引
第一种:EXPLAIN select id,t.teacherEmail from white_user t where whiteflag=1 and teacheremail='testdemo2';
第二种:EXPLAIN select id,t.teacherEmail from white_user t where teacheremail='testdemo2' and whiteflag=1 ;
第三种:EXPLAIN select id,t.teacherEmail from white_user t where teacheremail='testdemo2';
第四种:EXPLAIN select id,t.teacherEmail from white_user t where whiteflag=1 ;
Innodb引擎对哈希索引的使用
Innodb引擎有一个特殊的功能叫做“自适应哈希索引”,当Innodb注意到某些索引值被使用的非常频繁时,它会在内存中给予b-tree索引之上再创建一个哈希索引,这样就让b-tree索引页具有哈希索引的一些优点,比如快速哈希查找,这种完全自动的、内部的行文。
Innodb引擎可以模拟哈希索引,在表上创建一个伪哈希索引,也可以享受哈希索引 带来的便利,例如可以存储很小的索引就可以为超长的字段创建索引。
建议使用CRC32哈希函数,不建议使用SHA1和MD5哈希函数,因为后两个函数得出的哈希码非常长,会浪费大量空间,做比较时也慢。但是SHA1和MD5哈希函数进行的是强加密函数,设计目标是最大限度的消除冲突。
如果表非常大的话,CRC32哈希函数会出现大量哈希冲突,可以考虑自己实现一个64位的哈希函数。
举例:
CREATE TABLE `white_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`teacherEmail` varchar(30) DEFAULT NULL,
`whiteFlag` int(1) DEFAULT '0',
`hashCode` varchar(255) DEFAULT NULL,
`creationTime` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `PK_INDEX` (`teacherEmail`,`whiteFlag`) USING BTREE),
KEY `PK_HASHCODE` (`hashcode`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=64 DEFAULT CHARSET=utf8;
新增数据时,hashcode字段中应该存储CRC32(teacheremail)获得的哈希码
执行下面条件时,可以使用到
EXPLAIN select id,t.teacherEmail from white_user t where hashcode=CRC32('testdemo2') AND whiteflag=1 and teacheremail='testdemo2';
这样就可以利用哈希索引加快查询速度,同时对超大字段尽心索引。