MySQL btree索引与hash索引区别

2022-07-29,,,,

mysql中,大多数索引(如 primary key,unique,index和fulltext)都是在btree中存储,但使用memory引擎可以选择btree索引或者hash索引,两种不同类型的索引各自有其不同的使用范围。

  • b树索引具有范围查找和前缀查找的能力,对于有n节点的b树,检索一条记录的复杂度为o(logn)。相当于二分查找。
  • 哈希索引只能做等于查找,但是无论多大的hash表,查找复杂度都是o(1)。

显然,如果值的差异性大,并且以等值查找(=、 <、>、in)为主,hash索引是更高效的选择,它有o(1)的查找复杂度。
如果值的差异性相对较差,并且以范围查找为主,b树是更好的选择,它支持范围查找。

一、hash索引

利用哈希函数,计算存储地址,检索时不需要像btree那样,从根节点开始遍历,逐级查找。

hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像b-tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的io访问,所以 hash 索引的查询效率要远高于 b-tree 索引。

可能很多人又有疑问了,既然 hash 索引的效率要比 b-tree 高很多,为什么大家不都用 hash 索引而还要使用 b-tree 索引呢?任何事物都是有两面性的,hash 索引也一样,虽然 hash 索引效率高,但是 hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。

(1)hash 索引仅仅能满足”=”,”in”和”<=>”查询,不能使用范围查询(查询范围时 慢)。

由于 hash 索引比较的是进行 hash 运算之后的 hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 hash 算法处理之后的 hash 值的大小关系,并不能保证和hash运算前完全一样。

(2)hash 索引无法被用来避免数据的排序操作。

由于 hash 索引中存放的是经过 hash 计算之后的 hash 值,而且hash值的大小关系并不一定和 hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;

(3)hash 索引不能利用部分索引键查询。

对于组合索引,hash 索引在计算 hash 值的时候是组合索引键合并后再一起计算 hash 值,而不是单独计算 hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,hash 索引也无法被利用。

(4)hash 索引在任何时候都不能避免表扫描。

前面已经知道,hash 索引是将索引键通过 hash 运算之后,将 hash运算结果的 hash 值和所对应的行指针信息存放于一个 hash 表中,由于不同索引键存在相同 hash 值,所以即使取满足某个 hash 键值的数据的记录条数,也无法从 hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。

(5)hash 索引遇到大量hash值相等的情况后性能并不一定就会比b-tree索引高。

对于选择性比较低的索引键,如果创建 hash 索引,那么将会存在大量记录指针信息存于同一个 hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

二、b+树

  • b+树的查找过程

如图所示,如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次io,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的p2指针,内存时间因为非常短(相比磁盘的io)可以忽略不计,通过磁盘块1的p2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次io,29在26和30之间,锁定磁盘块3的p2指针,通过指针加载磁盘块8到内存,发生第三次io,同时内存中做二分查找找到29,结束查询,总计三次io。真实的情况是,3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次io,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次io,那么总共需要百万次的io,显然成本非常非常高。

  • b+树性质

1.索引字段要尽量的小:

通过上面的分析,我们知道io次数取决于b+数的高度h,假设当前数据表的数据为n,每个磁盘块的数据项的数量是m,则有h=㏒(m+1)n,当数据量n一定的情况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,如果数据项占的空间越小,数据项的数量越多,树的高度越低。这就是为什么每个数据项,即索引字段要尽量的小,比如int占4字节,要比bigint8字节少一半。这也是为什么b+树要求把真实的数据放到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度下降,导致树增高。当数据项等于1时将会退化成线性表。

2.索引的最左匹配特性(即从左往右匹配):

当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,f)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,f)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,f)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是f的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

以上就是mysql btree索引与hash索引区别的详细内容,更多关于mysql btree索引与hash索引的资料请关注其它相关文章!

《MySQL btree索引与hash索引区别.doc》

下载本文的Word格式文档,以方便收藏与打印。