热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析

Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析一.Mysql数据库常见存储引擎1.可以作为索引文件的数据结构:二叉树,红黑树,hash表,B-tree,B+tree,

Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析

一.Mysql数据库常见存储引擎

1.可以作为索引文件的数据结构:
二叉树,红黑树,hash表,B-tree,B+tree,但是二叉树,红黑树受到树高问题限制,hash表无法进行索引排序无法进行查询,B-tree无法充分利用非叶子节点的存储能力,所以在mysql数据库中最常用的索引存储数据结果为B+tree;

2.索引文件组织结构:
聚簇索引:索引字段+全部其他表字段保存在一个文件中,索引树的叶子节点即表中全量数据;
非聚簇索引:索引字段和表中全量字段分两个文件进行保存,索引树的叶子节点中存储对应全量数值在磁盘上的地址;

3.mysql数据库中常用的存储引擎:
MyISAM:采用非聚簇索引,不支持行级锁,不支持事 务;数据结构如下图所示:
《Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析》

innoDB:采用聚簇索引,支持行级锁,支持事务,MVCC机制等;数据结构如下图所示:
主键索引聚簇《Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析》
辅助索引非聚簇(但在叶子节点中会保存主键索引树中的对应的值,便于回表使用)
《Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析》

二.B+tree索引文件结构及索引树遍历情况
1.索引文件组织结构
非叶子节点不存储data,只存储索引(冗余),可以放更多b的索引
叶子节点包含所有索引字段
叶子节点用指针连接,提高区间访问的性能
如下图所示:
《Mysql中B+Tree索引结构、遍历次数、磁盘io次数分析》
在B+tree索引的表空间Tablespace 中具有以下几个概念:
• 段:一个索引2段:叶子节点Segment & 非叶子节点Segment;
• Extent(1MB):一个Extent(1M) 包含64个 Page(16k),一个Page里包含很多有序行数据 , InnoDB B-Tree 一个逻辑节点就分配一个物理Page;
• Page(16KB):B+tree中每个数据节点就是一个page

• Row:记录行

• Field:字段

2.MYISAM和innoDB索引树遍历过程
MYISAM存储引擎
MYISAM存储引擎中主键索引和辅助索引都都采用非聚簇形式,在磁盘中一共有三个文件进行数据存储分别为,数据数据定义文件,索引文件,数据文件;
执行数据查询时索引树的遍历流程为:
a.将磁盘索引文件的根节点的page加载到内存,进行二分查找定位到子节点的page,依次递归加载相应的page,找叶子节点data中磁盘地址;
b.根据data中的磁盘地址去数据文件中加载相应的数据到内存;

innoDB存储引擎
innoDB存储引擎的主键索引采用聚簇索引,辅助索引采用非聚簇;拥有一个数据定义文件和一个索引文件(索引+其+其它字段合并)
执行数据查询时索引树的遍历流程为:
主键索引: 确定定位条件, 找到根节点Page No, 根节点读到内存, 逐层向下查找, 读取叶子节点Page,通过 二分查找找到记录或未命中。
辅助索引:通过二级索引查出对应主键,拿主键回表查主键索引得到数据, 二级索引可筛选掉大量无效记录,提高效率( 回表就是通过辅助索引拿到主键id之后,要再去遍历聚集索引的B+树,这个过程就叫做回表。回表的操作更多的是随机io,随机io在性能上还是比较低)

全表扫描:直接读取叶节点头结点, 顺序扫描, 返回符合条件记录, 到最终节点结束

三.聚集索引和非聚集索引执行一次sql的io次数
磁盘io次数分析
(1) 数据量小的话,直接把索引放到内存中,内存的O(logn)消耗是远远低于磁盘io的,所以可以忽略不计
(2) 数据量大的话,采用索引结构,我们这部分先从二叉树说起,对于普通二叉树,第一个步骤是二分,每次判断都是一次半数的数量级检索。假如有100W的数据,大概的时间复杂度是:log2N=1000000即N=20的节点获取,也就是磁盘I/O复杂度最大为O(20),二分的时间复杂度是O(log2N)。
(3) 但是对于数据库来说,存储场景会更加复杂,二叉树的性能虽然好,但我们还是想要树的高度更低一些,存储的数据更多一些。因此mysql引入了B+树的概念。除了根节点之外,第二层级的数量得到了充分的扩展,相对于普通的二叉树,B+树的结构更加庞大又不失美感,假设非叶节点不同元素占用情况为:下一条记录指针占4Byte,id值8Byte,目标记录指针4Byte,那么一个4Kb的磁盘块将大致可以容纳250个下级指针,100万行目标记录(假设叶子节点也是只保存了id值,则一个非叶子节点下面也包括大概250个叶子节点)只需log250N=1000000即N=3的I/O次数,充分提升了每次节点I/O带来的检索效用,时间复杂度是O(lognN),这里的n是非叶子结点的个数。(PS:实际上innodb的数据页大小是16kb,这个n会更大,那么对应的,io次数也会更少)
(4) 在实际的查询中,IO次数可能会更小,因为有可能会把部分用到的索引读取到内存中,相对于磁盘IO来说,内存的io消耗可以忽略不计。一般来说B+Tree的高度一般都在2-4层,MySQL的InnoDB存储引擎在设计时是将根节点常驻内存的,也就是说查找某一键值的行记录时最多只需要1~3次磁盘I/O操作(根节点的那次不算磁盘I/O)。

多大的索引数据可以直接放到内存中
要参照自己的mysql设置,一般是innodb_buffer_pool_size的值,这个值默认是128M,具体的要根据机器的性能设置。


推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
author-avatar
手机用户2602931437
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有