存储数据方式:
Hash:是采用Key-Value的方式,键值key通过hash映射找到bucket桶的位置,这里的bucket桶指的是存储一条或多条的存储单位。一个bucket的结构包含了一个内存指针数组,桶中的每行数据都会指向下一行,形成链表结构,当出现hash冲突时,会在桶中出现键值的查找。
InnoDB中采用取余法,冲突机制采用链接发。
B+Tree:非叶子节点只存放索引,所有的数据存放在叶子节点,叶子节点中间存在双向指针,用于范围查询。
查询性能:
- 如果是等值查询,hash索引占有绝对的优势,因为只需要经过一次hash算法即可找到相应的键值,复杂度为O(1);当然,前提键值都是唯一的,如果不唯一或者存在Hash冲突,就需要找到该key所在的位置,并且循环链表,直到找到相应数据,这个时候复杂度O(n),降低了hash索引的查询效率。所以,Hash索引不会用到重复列上。
- Hash是无序的,如果是范围查询,那么Hash索引就无法起到作用,即使原先是有序的键值,经过hash算法后,也会变成不连续的了。因此:
2.1、hash索引只支持等值的比较查询、无法实现范围检索,B+tree索引的叶子节点形成有序链表,便于范围查询。
2.2、hash索引无法做like ‘xxx%’ 这样的部分模糊查询,因为需要对完整key做hash计算,定位bucket,而B+tree索引具有最左前缀匹配,可以进行部分模糊查询
2.3、hash索引中存放的是经过hash计算之后的hash值,而且hash值的大小关系并不一定和hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算,B+tree索引的叶子节点形成有序的链表,可用于排序。
3.Hash索引不支持多列联合索引,对于联合索引来说,Hash索引在计算Hash值的时候是将索引键合并在一起计算hash值,不会针对每个索引单独计算hash值。因此如果用到联合索引得端一个或者几个索引时,联合索引无法使用。
4.因为存在hash碰撞的问题,在有大量重复值的列,hash索引的效率地下,B+tree所有查询都要找到叶子节点,性能稳定。
使用场景
- 若字段会出现大量重复数据、检索需要排序、分组、范围查询、模糊查询等操作,hash无法满足要求,建议使用B+Tree.
2.在离散型高,数据基数大,且等值查询得时候,Hash索引有优势。
这篇文章大部分都是参考别人写的,仅仅是为了记录一下,觉得这篇原作者写的很好,就总结了一下