不积跬步无以至千里

记录精彩的程序人生

  • 首页
  • Java
  • Golang
  • PHP
  • Python
  • Nodejs
  • Lua
  • Docker
  • DevOps
  • 文章归档
  • 默认分类
  • 关于
  • 标签

  • 搜索
PostgreSQL hbase 时间同步 nexus 开机启动 nexus, 开机启动 jenkins安装配置 gitlab安装配置 gitlab安装 文件系统 fastdfs gcc切换 gcc升级 mysql8 交换空间 虚拟内存 tcp thrift lua tag test VPN SoftEtherVPN homebrew asm spring tomcat maven jdk ios mac 图案字符 figlet mysql半同步复制 mysql主从同步 一主多从 一主一从 主从同步 反向代理 密码重置 test 虚拟机扩容 swap 虚拟空间 docker ldocker grpc-gateway protobuf 微服务 go grp GRPC 授权登录 OAuth2.0 SOA supervisord supervisor RPC CentOS rabbitmq 环境变量 php-fpm php.ini error php7 lnmp 编译安装 mysql nginx linux java php python redis 字符串操作 mysql5.7 Solo

MySQL B+树索引和哈希索引的区别

发表于 2021-09-19 | 分类于 默认分类 | 0 | 阅读次数 1323

导读

在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议。

二者区别

备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTREE,例如像下面这样的写法:
CREATE TABLE t( aid int unsigned not null auto_increment, userid int unsigned not null default 0, username varchar(20) not null default ‘’, detail varchar(255) not null default ‘’, primary key(aid), unique key(uid) USING BTREE, key (username(12)) USING BTREE — 此处 uname 列只创建了最左12个字符长度的部分索引 )engine=InnoDB;
一个经典的B+树索引数据结构见下图: (图片源自网络)

B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接。

在B+树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。

因此,B+树索引被广泛应用于数据库、文件系统等场景。顺便说一下,xfs文件系统比ext3/ext4效率高很多的原因之一就是,它的文件及目录索引结构全部采用B+树索引,而ext3/ext4的文件目录结构则采用Linked list, hashed B-tree、Extents/Bitmap等索引数据结构,因此在高I/O压力下,其IOPS能力不如xfs。

详细可参见:

https://en.wikipedia.org/wiki/Ext4
https://en.wikipedia.org/wiki/XFS

而哈希索引的示意图则是这样的:

(图片源自网络)

简单地说,哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快。

从上面的图来看,B+树索引和哈希索引的明显区别是:

  • 如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值;当然了,这个前提是,键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据;
  • 从示意图中也能看到,如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;
  • 同理,哈希索引也没办法利用索引完成排序,以及like ‘xxx%’ 这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);
  • 哈希索引也不支持多列联合索引的最左匹配规则;
  • B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在所谓的哈希碰撞问题。

后记

在MySQL中,只有HEAP/MEMORY引擎表才能显式支持哈希索引(NDB也支持,但这个不常用),InnoDB引擎的自适应哈希索引(adaptive hash index)不在此列,因为这不是创建索引时可指定的。

还需要注意到:HEAP/MEMORY引擎表在mysql实例重启后,数据会丢失。

通常,B+树索引结构适用于绝大多数场景,像下面这种场景用哈希索引才更有优势:

在HEAP表中,如果存储的数据重复度很低(也就是说基数很大),对该列数据以等值查询为主,没有范围查询、没有排序的时候,特别适合采用哈希索引

例如这种SQL:
SELECT … FROM t WHERE C1 = ?; — 仅等值查询


在大多数场景下,都会有范围查询、排序、分组等查询特征,用B+树索引就可以了。

转自:http://www.cnblogs.com/zengkefu/p/5647279.html

Springboot 版本+ jdk 版本 + Maven 版本的匹配
thrift安装文档
  • 文章目录
  • 站点概览
ken

ken

记录精彩的程序人生

498 日志
9 分类
77 标签
RSS
Creative Commons
Links
  • 酷壳
0%
© 2010 — 2025 ken
由 Halo 强力驱动
鄂ICP备18013899号-1