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