哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码,哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。
在mysql中,只有Memory引擎显式支持哈希索引。这也是memory引擎表的默认索引类型,memory引擎同时也支持B-Tree索引。 值得一提的是memory是支持非唯一哈希索引的
哈希索引的限制
1、哈希索引只包含哈希值和行指针,并不存储字段值,所以不能使用索引中的值来避免读取行。不过,访问内存中的行速度很快,所以大部分情况下,这一点对性能的影响不是很明显。
2、哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序。
3、哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内网来计算哈希值的。例如,数据列(A,B)上建立哈希索引,如果查询只有数据列A,则无法使用该索引。
4、哈希索引只支持等值比较查询,包括=、in()、<=>(注意<>和<=>是不同的操作)。也不支持任何范围查询,例如,where price > 100
5、访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所以的行指针,逐行进行比较,直到找到所有符合条件的行
6、如果哈希冲突很多的话,一些索引为何操作的代价也会很高。例如,如果某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大
处理哈希冲突
要避免冲突,必须在where条件中代入哈希值和对应列值。如果不是像查询具体指,例如只是统计记录数(不精确),则可以不带入列值,直接使用CRC32()的哈希值查询即可。
原文地址:https://www.cnblogs.com/kevinleerunqing/p/12034342.html