在使用MySQL数据库的时候,索引是我们经常会用到的东西,MySQL大部分引擎通常支持HASH和B-TREE两种方式去创建索引,那么到底该如何选择呢,什么情况用hash索引什么情况用btree索引,我们来看看二者的区别
BTree
BTree (in fact B*Tree) is an efficient ordered key-value map. Meaning:
- given the key, a BTree index can quickly find a record,
- a BTree can be scanned in order.
- it's also easy to fetch all the keys (and records) within a range.
Hash
Hash is an unordered key-value map. It's even more efficient than a BTree: O(1) instead of O(log n).
But it doesn't have any concept of order so it can't be used for sort operations or to fetch ranges.
As a side note, originally, MySQL only allowed Hash indexes on MEMORY tables; but I'm not sure if that has been changed over the years.
- Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
-Hash 索引无法被用来避免数据的排序操作。由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
- Hash 索引不能利用部分索引键查询。对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
- Hash 索引在任何时候都不能避免表扫描。前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
- Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。
Hash还是Btree
最后做一个小结,除非你非常明确你的业务更适合Hash,大多数情况我们还是使用Btree的,也是默认的索引方式,因为它基本覆盖了所有的使用场景,并且效果还不错。
viencoding.com版权所有,允许转载,但转载请注明出处和原文链接: https://viencoding.com/article/194
欢迎小伙伴们在下方评论区留言 ~ O(∩_∩)O
文章对我有帮助, 点此请博主吃包辣条 ~ O(∩_∩)O
There are no comments yet.