在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 index fulltext btree_MySQL btree索引与hash索引区别相关推荐

  1. MySQL的btree索引和hash索引的区别

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

  2. MySQL中B-tree索引和Hash索引区别

    在MySQL文档里,实际上是把B+树索引写成了BTREE,例如像下面这样的写法: CREATE TABLE t(aid int unsigned not null auto_increment,use ...

  3. mysql btree检索策略_MySQL之Btree索引和HASH索引的区别以及索引优化策略

    索引是帮助mysql获取数据的数据结构.最常见的索引是Btree索引和Hash索引. 不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引:而Mermory默认的索引是 ...

  4. mysql hash索引 btree索引_B-Tree索引与Hash索引的比较

    B-Tree索引与Hash索引的比较 理解B-Tree和Hash的数据结构能够帮助我们预测不同存储引擎下的查询性能差异.存储引擎在索引中使用这些数据结构,尤其是MEMORY 同时提供了B-Tree和H ...

  5. MySQL索引类型 btree索引和hash索引的区别

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

  6. hash 值重复_MySQL调优实战:MySQL B+Tree索引和Hash索引的区别?

    点击上方"Java分享吧",选择"设为星标" 优选有价值的技术文献,从我做起 MySQL技术篇章 1.B+Tree索引 1.B+Tree首先是有序结构,为了不至 ...

  7. mysql索引b树和hash_B树索引和Hash索引的应用场景和区别(转载)

    转自:https://blog.csdn.net/chuangsun/article/details/78013537 关系型数据库中,索引大多采用B/B+树来作为存储结构,而全文搜索引擎的索引则主要 ...

  8. MySQL-Btree索引和Hash索引初探

    文章目录 生猛干货 官方文档 MySQL支持的索引类型 B树索引 B树索引的特点 什么情况下会使用到B树索引 Btree索引的使用限制 hash索引 hash索引的特点 hash索引的限制 为啥要使用 ...

  9. java实践7索引之Hash索引、位图索引、倒排索引原理

    文章目录 java实践7索引之Hash索引.位图索引.倒排索引原理 Hash索引 优缺点: 位图索引: 优缺点: 倒排索引: B树+倒排索引 java实践7索引之Hash索引.位图索引.倒排索引原理 ...

最新文章

  1. mysql5.7+ 虚拟列,json使用初体验
  2. BCP utility in Sybase(Unix Environment)
  3. linux的tcpdump命令详解,tcpdump命令
  4. 大牛深入讲解!高并发你真的理解透彻了吗
  5. Oracle adviser,Oracle10g SQL tune adviser
  6. 一维序列卷积之Python实现
  7. 联网智能设备安全态势季度报告(2021年第2季度)
  8. 身份证号每一位号码的意义
  9. IOS开发学习笔记033-UIScrollView
  10. IT人 不要一辈子靠技术生存(转
  11. GitHub使用笔记
  12. docker安装gamit_Ubuntu 14.04下Gamit10.5安装
  13. 读书笔记—情商:为什么情商比智商更重要
  14. 如何理解keras中的shape/input_shape
  15. php小型购物网站,PHP实现一个多功能购物网站
  16. Java 培训四个月能学会吗?
  17. 阿里天池:Airbnb短租房数据集分析
  18. 解决mac idea2020打开闪退问题
  19. componentWillReceiveProps为什么deprecated
  20. 用js代码判断质数_Js关于质数的判定

热门文章

  1. 安卓开发裕语言程序---调用qq收藏作为远程更新实例
  2. REGENCY HAMPERS案例分享:使用 Aspose.PSD 渲染用户定义的图像
  3. C++、构造函数与拷贝构造函数
  4. 编译java程序的主命令_编译Java程序的命令是:()
  5. viper4android acg,2020提升手机音质必备APP,VIPER HiFi 千万级无损曲库
  6. 华为手环8和华为手环7的区别
  7. 小伙艰苦努力三个月后在七月成功斩获饿了么Offer「Java研发岗」
  8. 癌症基因图谱( TCGA)数据库(二)数据前处理
  9. Learning FileMaker Go 15 学习FileMaker Go 15 Lynda课程中文字幕
  10. 100道计算机故障检测试题,计算机故障检测与维护项目测试题:计算机系统维护测试题(一).docx...