02_MySQL的索引结构

news2024/11/29 12:42:53

1. BTree索引

  • B-Tree即B树,Balance Tree,平衡树,它的高度远小于平衡二叉树的高度。
  • 2-3树是最简单的B树结构。
  • B树的阶:节点的最多子节点个数。比如2-3树的阶是3,2-3-4树的阶是4。

1.1 初始化介绍

一颗b树,浅蓝色的块我们称之为一个磁盘块(innodb默认16kb一个磁盘块),可以看到每个磁盘块包含几个数据项(深蓝色所示)、指向关键字具体信息的指针(红色)和指向其他磁盘块的指针(黄色所示)如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。

1.2 查找过程

如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。

1.3 真实的情况

3层的b树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

2. B+Tree索引

2.1 数据结构

2.2 B+Tree与B-Tree 的区别

B-树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;

B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中。树的高度会更矮胖,IO次数也会更少。

在B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。从这个角度看B-树的性能好像要比B+树好,而在实际应用中却是B+树的性能要好些。因为B+树的非叶子节点不存放实际的数据,这样每个节点可容纳的元素个数比B-树多,树高比B-树小,这样带来的好处是减少磁盘访问次数。尽管B+树找到一个记录所需的比较次数要比B-树多,但是一次磁盘访问的时间相当于成百上千次内存比较的时间,因此实际中B+树的性能可能还会好些,而且B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有文件,一个表中的所有记录等),这也是很多数据库和文件系统使用B+树的缘故。  

思考:为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引?

① B+树的磁盘读写代价更低   

B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

② B+树的查询效率更加稳定   

由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

2.3 数据页大小

查看mysql文件页大小(16K):

SHOW GLOBAL STATUS LIKE '%page_size%'

为什么mysql页文件默认16K?

假设我们一行数据大小为1K,那么一页就能存16条数据,也就是一个叶子节点能存16条数据;再看非叶子节点,假设主键ID为bigint类型,那么长度为8B,指针大小在Innodb源码中为6B,一共就是14B,那么一页里就可以存储16K/14B=1170个(主键+指针)

一颗高度为2的B+树能存储的数据为:1170*16=18720条
一颗高度为3的B+树能存储的数据为:1170*1170*16=21902400(千万级)

3. 聚簇索引与非聚簇索引

3.1 聚簇索引

  • 将数据存储与索引放到了一块,找到索引也就找到了数据。
  • 页内的记录是按照主键的大小顺序排成一个单向链表 。
  • 页和页之间也是根据页中记录的主键的大小顺序排成一个双向链表 。
  • 非叶子节点存储的是记录的主键+页号。叶子节点存储的是完整的用户记录。

3.2 非聚簇索引

将数据存储与索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因。

3.3 澄清一个概念

innodb中,非聚簇索引又称辅助索引,辅助索引访问数据总是需要二次查找。辅助索引叶子节点存储的不再是行的物理位置,而是主键值。

InnoDB使用聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据

对Name列进行条件搜索,则需要两个步骤第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。(重点在于通过其他键需要建立辅助索引

3.4 聚簇索引的好处

  • 由于行数据和叶子节点存储在一起,同一页中会有多条行数据,访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。这样主键和行数据是一起被载入内存的,找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快

  • 聚簇索引适合用在排序的场合,非聚簇索引不适合

  • 取出一定范围数据的时候,使用聚簇索引

  • 二级索引需要两次索引查找,而不是一次才能取到数据,因为存储引擎第一次需要通过二级索引找到索引的叶子节点,从而找到数据的主键,然后在聚簇索引中用主键再次查找索引,再找到数据

3.5 聚簇索引的限制

  • 对于mysql数据库目前只有innodb数据引擎支持聚簇索引,而Myisam并不支持聚簇索引。

  • 由于数据物理存储排序方式只能有一种,所以每个Mysql的表只能有一个聚簇索引。

    • 一般情况下就是该表的主键。

    • 如果没有primary key,会以(not null unique key)非空的唯一索引保存数据

    • 内部自己生成一个字段保存数据

  • 为了充分利用聚簇索引的聚簇的特性,所以innodb表的主键列尽量选用有序非空的字段,而不建议用无序的id,比如uuid这种。

4. 回表

通过非聚簇索引查找到主键值之后仍然需要到聚簇索引中再查询一遍,这个过程称为回表

为什么我们还需要一次回表操作呢?直接把完整的用户记录放到叶子节点不OK吗?

如果把完整的用户记录放到叶子节点是可以不用回表。但是太占地方了,相当于每建立一棵B+树都需要把所有的用户记录再都拷贝一遍,这就有点太浪费存储空间了。

5. 联合索引

基于多个字段创建的索引就是联合索引,也称为复合索引,比如我们创建索引create index idx on table(a,b,c) 我们称在字段a,b,c上创建了一个联合索引。同时以这三个列的大小作为排序规则。

  • 记录先按照a列排序

  • a列值相同时使用b列排序

  • b列值相同时使用c列排序

然后将排好序的abc三列的值组织到非聚簇索引索引结构中。

联合索引结构:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/626277.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是AI业务流程质检,如何用它做好销售和服务过程监督

近几年,随着语音转写、语义理解和机器学习等技术的成熟,越来越多的企业开始部署基于AI技术的智能质检系统,来帮助坐席、销售和服务团队提高沟通质量管理能力,同时提升沟通中的客户体验。 不过,不论是最初的人工质检&a…

【Word技巧】打印部分内容或者隐藏不打印的内容,如何操作?

在工作中,我们经常需要打印各种Word文档,但有时候,我们只需要打印文档的其中一部分内容,或者有部分内容并不想打印出来,要如何操作呢? 还不了解的小伙伴,可以看看下面的方法哦。 一、设置打印其…

node.js+vue药品药店进销存管理系统jb526

开发语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode 重点研究的,关键的问题: (1)业务流程; (2)前台…

广发证券传媒互联网首席分析师旷实:大模型引发的创新浪潮不会很快结束丨数据猿专访...

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 AI大模型引爆了今年一季度的热点。 今年春节期间,来自微软投资的OpenAI旗下产品ChatGPT成为科技行业关注焦点,出现即推热了市场情绪。随后,国内百度首发文心一言,阿里、华为、…

DevExpress WPF功能区控件,更轻松创建应用工具栏!(上)

DevExpress WPF的Ribbon、Toolbar和Menus组件以Microsoft Office为灵感,针对WPF开发人员进行了优化,可帮助您在段时间内模拟当今最流行的商业生产力应用程序。 DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业…

深度学习应用篇-计算机视觉-语义分割综述[6]:DeepLab系列简介、DeepLabV3深入解读创新点、训练策略、主要贡献

【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化…

MATLAB 之 数值积分和离散傅里叶变换

这里写目录标题 一、数值积分1. 数值积分基本原理2. 数值积分的实现2.1 变步长辛普森法2.2 自适应积分法2.3 高斯——克朗罗德法2.4 梯形积分法2.5 累计梯形积分 3. 多重定积分的数值求解 二、离散傅里叶变换1. 离散傅里叶变换算法简介2. 离散傅里叶变换的实现 一、数值积分 数…

通信算法之167: (低空无人机)机载通信物理层基带算法设计

一.物理层基带仿真 通信系统的链路级仿真主要可以分成5个部分。 1.系统参数 2.发送机算法 3.信道模型 4.接收机算法 5.统计性能 其中主要组成部分很明显是中间三部分,即发送,信道,接收。但系统参数和统计性能这两部分的适当设计会大大…

在webpack中使用Eslint

一、Eslint介绍 要在webpack中使用Eslint首先我们先了解下什么是Eslint 1. 什么是Eslint ESLint是一个用于在JavaScript代码中发现和报告问题的静态代码分析工具。它可以检测常见的编码错误,如拼写错误、变量未声明、使用未定义的变量等,还可以检测代…

1.3C++运算符重载规则

C运算符重载规则 重载的运算符必须是C中已有的运算符。 重载运算符的参数个数必须与原来的运算符相同。 重载运算符的优先级和结合性与原来的运算符相同。 重载运算符必须是类的成员函数或全局函数。 重载运算符不能改变原有的语义。 不能改变运算符的操作数类型&#xf…

sqoop系列:sqoop(离线数据同步)采集节点安装

目录 1:安装包准备 2:添加环境变量 3:配置部署 3.1) 修改sqoop-env.sh 3.2) 验证安装是否成功 3.3) 测试Sqoop是否能够成功连接数据库 报错:Exception in thread "main" java.lang.NoClassDefFoundError: org/apa…

【023】C/C++数据结构之链表及其实战应用

C 链表及其实战应用 引言一、链表的概述二、利用链表设计一个学生管理系统2.1、设计主函数main()2.2、实现插入节点2.3、实现链表的遍历2.4、实现链表的查找2.5、实现删除某个节点2.6、实现释放链表2.7、完整代码 总结 引言 💡 作者简介:专注于C/C高性能…

纠删码技术在vivo存储系统的演进【上篇】

作者:vivo 互联网服务器团队- Gong Bing 本文将学术界和工业界的纠删码技术的核心研究成果进行了相应的梳理,然后针对公司线上存储系统的纠删码进行分析,结合互联网企业通用的IDC资源、服务器资源、网络资源、业务特性进行分析对原有纠删码技…

连杆滑块伸缩模组的制作

1. 运动功能说明 连杆滑块伸缩模组的主要运动方式为舵机带动滑块沿着光轴平行方向做伸缩运动。 2. 结构说明 本模组主要是由舵机、滑块、光轴、连杆等组成。 3. 电子硬件 在这个示例中,我们采用了以下硬件,请大家参考: 主控板 Basra主控板&…

耗时5个月,我做了一块高性能的开发板

本文项目工程选自:https://oshwhub.com/logicworld/h6_board 原作者 logicworld 本项目开源主要目的是帮助想学ARM高速电路的小伙伴们,学会自己做一个ARM开发板。教程从最初的“需求分析”一直到成功实现“软硬件联调”,就算是0基础的硬件小…

Vue中的指令与自定义指令

目录 Vue中的指令 v-xxx指令汇总 v-text v-html v-cloak v-once v-pre 自定义指令 函数式 对象式 Vue中的指令 v-xxx指令汇总 之前学过的指定: v-bind :单向绑定解析表达式,可简写为:xxx v-model :双向数据绑定 v-for …

【Python】Python进阶系列教程-- Python3 CGI编程(二)

文章目录 前言什么是CGI网页浏览CGI架构图Web服务器支持及配置第一个CGI程序HTTP头部CGI环境变量GET和POST方法使用GET方法传输数据简单的表单实例:GET方法使用POST方法传递数据通过CGI程序传递checkbox数据通过CGI程序传递Radio数据通过CGI程序传递 Textarea 数据通…

展会ING丨计讯物联在中国水博览会大放异彩,现场人气持续狂飙

6月7日,由中国水利学会和中国水利工程协会联合打造的的2023中国水博览会暨第十八届中国(国际)水务高峰论坛于江苏南京国际展览中心盛大举行,超过40多个国家和地区的2450余家展商如约而至,超24万人次的专业观众齐聚一堂…

PLC与IO模块之间搭建1主多从网口无线通讯

想实现西门子PLC通过网口无线采集多处分散IO信号,实际上就是,在Profinet通讯协议下,通过RJ45口,搭建一个西门子PLC与IO模块之间1主多从的无线以太网通讯网络。我们就需要以下几种设备来搭建无线网络: 1.西门子PLC&…

线程池源码解读及原理

前言 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不过年轻人,升迁也无望,于是拿着手里的一些积蓄,回老家转行创业。他选择了洗浴行业,开一家洗浴中心,没错,一…