【mysql】聚簇索引和非聚簇索引(B树和B+树)

news2024/11/24 15:39:59

  • 博主简介:想进大厂的打工人
  • 博主主页:@xyk:
  • 所属专栏: mysql

目录

一、索引分类

二、索引的数据结构

2.1 B树:改造二叉树

2.2 B+树:改造B树

三、Mysql索引实现—InnoDB引擎

3.1 主键索引(聚簇索引)

3.2 辅助索引(非聚簇索引)

3.3 避免回表

3.4 覆盖索引


一、索引分类

索引一般可以分为以下几类:

主键索引:主键索引是一种特殊的索引类型,它是用于唯一标识每一行数据的索引,每个表只能有一个主键索引,索引列中的值必须是唯一的,不允许有空值。

复合索引:复合索引也叫多列索引或联合索引,它是包含多个列的索引类型,能够加速多列查询和排序操作。需要遵循最左前缀匹配原则(最左匹配原则)

普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值。

唯一索引:唯一索引是用来保证列的唯一性的索引,一个表可以有多个唯一索引。比如说,因为人有可能同名,所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。索引列中的值必须是唯一的,但是允许为空值。

全文索引:全文索引是一种用于全文搜索的索引类型,能够对文本数据进行快速的模糊搜索和关键字搜索。只能在文本类型CHAR,VARCHAR,TEXT类型字段上创建全文索引。

哈希索引:哈希索引是基于哈希表实现的索引类型,能够对等值查询进行高效的处理,但不支持范围查询和排序,MySQL 中 Memory 引擎中支持哈希索引。

二、索引的数据结构

Hash表

Hash表,在Java中的HashMap,TreeMap就是Hash表结构,以键值对的方式存储数据。我们使用Hash表存储表数据Key可以存储索引列,Value可以存储行记录或者行磁盘地址。Hash表在等值查询时效率很高,时间复杂度为O(1);但是不支持范围快速查找,范围查找时还是只能通过扫描全表方式。

2.1 B树:改造二叉树

MySQL的数据是存储在磁盘文件中的,查询处理数据时,需要先把磁盘中的数据加载到内存中,磁盘IO操作非常耗时,所以我们优化的重点就是尽量减少磁盘IO操作。访问二叉树的每个结点就会发生一次IO,如果想要减少IO操作,就需要降低树的高度。

假如key为bigint=8字节,每个节点有两个指针,每个指针为4个字节,一个节点占用的空间16个字节(8+4*2=16)。

因为在MySQL的InnoDB存储引擎一次IO会读取的一页(默认一页16K)的数据量,而二叉树一次IO有效数据量只有16字节,空间利用率极低。为了最大化利用一次IO空间,一个简单的想法是在每个节点存储多个元素,在每个节点尽可能多的存储数据。每个节点可以存储1000个索引(16k/16=1000),这样就将二叉树改造成了多叉树,通过增加树的叉树,将树从高瘦变为矮胖。构建1百万条数据,树的高度只需要2层就可以(1000*1000=1百万),也就是说只需要2次磁盘IO就可以查询到数据。磁盘IO次数变少了,查询数据的效率也就提高了。

这种数据结构我们称为B树,B树是一种多叉平衡查找树,如下图主要特点:

  1. B树的节点中存储着多个元素,每个内节点有多个分叉。
  2. 节点中的元素包含键值和数据,节点中的键值从大到小排列。也就是说,在所有的节点都储存数据。
  3. 父节点当中的元素不会出现在子节点中。
  4. 所有的叶子结点都位于同一层,叶节点具有相同的深度,叶节点之间没有指针连接。

在这里插入图片描述

 举个例子:

假如我们查询值等于10的数据。查询路径磁盘块1->磁盘块2->磁盘块5。

第一次磁盘IO:将磁盘块1加载到内存中,在内存中从头遍历比较,10<15,走左路,到磁盘寻址磁盘块2。

第二次磁盘IO:将磁盘块2加载到内存中,在内存中从头遍历比较,7<10,到磁盘中寻址定位到磁盘块5。

第三次磁盘IO:将磁盘块5加载到内存中,在内存中从头遍历比较,10=10,找到10,取出data,如果data存储的行记录,取出data,查询结束。如果存储的是磁盘地址,还需要根据磁盘地址到磁盘中取出数据,查询终止。

相比二叉平衡查找树,在整个查找过程中,虽然数据的比较次数并没有明显减少,但是磁盘IO次数会大大减少。同时,由于我们的比较是在内存中进行的,比较的耗时可以忽略不计。B树的高度一般2至3层就能满足大部分的应用场景,所以使用B树构建索引可以很好的提升查询的效率。

过程如图:

在这里插入图片描述

看到这里你一定觉得B树很理想了,但是B树不支持范围查询的快速查找,如果我们想查询15-30之间的数据,查到15之后,我们还要返回根节点重新遍历查找下一个数据,直到全部遍历找到。

如果data存储的是行记录,行的大小随着列数的增多,所占空间会变大。这时,一个页中可存储的数据量就会变少,树相应就会变高,磁盘IO次数就会变大。

2.2 B+树:改造B树

B+树,作为B树的升级版,在B树基础上,MySQL在B树的基础上继续改造,使用B+树构建索引。B+树和B树最主要的区别在于非叶子节点是否存储数据的问题

  • B树:非叶子节点和叶子节点都会存储数据。
  • B+树:只有叶子节点才会存储数据,非叶子节点至存储键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序链表。

在这里插入图片描述

范围查询:
假如我们想要查找9和26之间的数据。查找路径是磁盘块1->磁盘块2->磁盘块6->磁盘块7。

  1. 首先查找值等于9的数据,将值等于9的数据缓存到结果集。这一步和前面等值查询流程一样,发生了三次磁盘IO。
  2. 查找到15之后,底层的叶子节点是一个有序列表,我们从磁盘块6,键值9开始向后遍历筛选所有符合筛选条件的数据。
  3. 第四次磁盘IO:根据磁盘6后继指针到磁盘中寻址定位到磁盘块7,将磁盘7加载到内存中,在内存中从头遍历比较,9<25<26,9<26<=26,将data缓存到结果集。
  4. 主键具备唯一性(后面不会有<=26的数据),不需再向后查找,查询终止。将结果集返回给用户。

在这里插入图片描述

  1. B+树的节点中可存N个key,N个key划分出N个区间,树的高度是相对矮的。
  2. 所有父节点都会重复出现在子节点中,从左到右依次递增
  3. 非叶子结点只起索引作用, 叶子结点包含信息。
  4. 非叶子结点可能在内存中缓存
  5. 所有的叶子结点都位于最后一层,叶节点之间首尾连接,所有key值都在子节点中存在,且最大为key

MySQL的索引就采用了B+树的数据结构。

三、Mysql索引实现—InnoDB引擎

3.1 主键索引(聚簇索引)

聚集索引:指索引项的排序方式和表中数据记录排序方式一致的索引。聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。

每个InnoDB表都有一个聚簇索引 ,聚簇索引使用B+树构建,叶子节点存储的数据是整行记录。一般情况下,聚簇索引等同于主键索引,当一个表没有创建主键索引时,InnoDB会自动创建一个ROWID字段来构建聚簇索引。

除聚簇索引之外的所有索引都称为辅助索引。在中InnoDB,辅助索引中的叶子节点存储的数据是该行的主键值。在检索时,InnoDB使用此主键值在聚簇索引中搜索行记录。

在这里插入图片描述

select * from user_innodb where id = 28;

在这里插入图片描述

  1. 先在主键树中从根节点开始检索,将根节点加载到内存,比较28<75,走左路。(1次磁盘IO)
  2. 将左子树节点加载到内存中,比较16<28<47,向下检索。(1次磁盘IO)
  3. 检索到叶节点,将节点加载到内存中遍历,比较16<28,18<28,28=28。查找到值等于28的索引项,直接可以获取整行数据。将改记录返回给客户端。(1次磁盘IO)
     

磁盘IO数量:3次。

3.2 辅助索引(非聚簇索引)

非聚集索引: 索引顺序与物理存储顺序不同

在这里插入图片描述

除聚簇索引之外的所有索引都称为辅助索引,InnoDB的辅助索引只会存储主键值而非磁盘地址.

在这里插入图片描述

使用辅助索引需要检索两遍索引:首先检索辅助索引获得主键,然后使用主键到主索引中检索获得记录。

select * from t_user_innodb where age=19;

在这里插入图片描述

根据在辅助索引树中获取的主键id,到主键索引树检索数据的过程称为回表查询。

磁盘IO数:辅助索引3次+获取记录回表3次

3.3 避免回表

在InnoDB的存储引擎中,使用辅助索引查询的时候,因为辅助索引叶子节点保存的数据不是当前记录的数据而是当前记录的主键索引,索引如果需要获取当前记录完整数据就必然需要根据主键值从主键索引继续查询。这个过程我们成位回表。想想回表必然是会消耗性能影响性能。那如何避免呢?

使用索引覆盖,举个例子:现有User表(id(PK),name(key),sex,address,hobby…)

如果在一个场景下,select id,name,sex from user where name ='zhangsan';这个语句在业务上频繁使用到,而user表的其他字段使用频率远低于它,在这种情况下,如果我们在建立 name 字段的索引的时候,不是使用单一索引,而是使用联合索引(name,sex)这样的话再执行这个查询语句是根据辅助索引查询到的结果就可以获取当前语句的完整数据。这样就可以有效地避免了回表再获取sex的数据。

3.4 覆盖索引

覆盖索引并不是说是索引结构,覆盖索引是一种很常用的优化手段。因为在使用辅助索引的时候,我们只可以拿到主键值,相当于获取数据还需要再根据主键查询主键索引再获取到数据。但是试想下这么一种情况,在上面abc_innodb表中的组合索引查询时,如果我只需要abc字段的,那是不是意味着我们查询到组合索引的叶子节点就可以直接返回了,而不需要回表。这种情况就是覆盖索引。

覆盖索引的情况:
在这里插入图片描述

未使用到覆盖索引:

在这里插入图片描述

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

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

相关文章

如何利用plotly和geopandas根据美国邮政编码(Zip-Code)绘制美国地图

对于我自己来说&#xff0c;该需求源自于分析Movielens-1m数据集的用户数据&#xff1a; UserID::Gender::Age::Occupation::Zip-code 1::F::1::10::48067 2::M::56::16::70072 3::M::25::15::55117 4::M::45::7::02460 5::M::25::20::55455 6::F::50::9::55117我希望根据Zip-…

Python读写csv文件

简介 通过Python内置csv模块&#xff0c;可以读取和写入CSV&#xff08;逗号分隔值&#xff09;文件。 CSV是一种常见的文件格式&#xff0c;通常用于存储表格数据&#xff0c;每行数据由逗号分隔&#xff0c;每个字段可以用引号括起来。 测试文件内容如下 列号,年龄,姓名,性别…

香橙派Zero2安装wiringPi外设库

安装wiringOP库 直接在香橙派上下载 wiringOP 的代码 sudo apt update sudo apt install -y git git clone https://github.com/orangepi-xunlong/wiringOP 如果在香橙派上下载不下来&#xff0c;也可以在通过windows浏览器打开https://github.com/orangepi-xunlong/wiringOP …

【【高级程序设计语言C++】C++多态的概念及原理

1. 多态的概念2. 多态的定义及实现2.1. 多态的条件2.2. 虚函数2.3. 虚函数的重写2.4. 虚函数重写的两个例外2.5. C11的override和final2.6. 重载、重写、重定义的对比 3. 抽象类3.1. 概念3.2. 实现继承和接口继承的对比 4. 多态的原理4.1. 虚函数表4.2. 多态原理4.3. 动态绑定和…

(34)继电器开关

文章目录 前言 34.1 装有IOMCU的自动驾驶仪上的继电器引脚 34.2 通过任务规划器定义继电器引脚 34.3 飞行员控制继电器 34.4 任务控制继电器 34.5 任务规划器控制继电器 前言 "继电器"是自动驾驶仪上的一个数字输出引脚&#xff0c;可在 0V 和 3.3V 或 5V 之间…

商城-学习整理-基础-分布式组件(三)

目录 一、前言二、Spring Cloud&Spring Cloud Alibaba1、Spring Cloud 与Spring Cloud Alibaba简介2、为什么使用Spring Cloud Alibaba3、版本选择4、项目中的依赖 三、Spring Cloud Alibaba-Nacos作为注册中心1、Nacos1&#xff09;、下载 nacos-server2&#xff09;、启动…

【C++ 程序设计】第 1~9 章:常见知识点汇总

目录 一、C 语言简介 二、面向对象的基本概念 三、类和对象进阶 四、运算符重载 五、类的继承与派生 六、多态与虚函数 七、输入/输出流 八、文件操作 九、函数模板与类模板 一、C 语言简介 知识点名称内容C语言的发展简史★★1. C 语言是 C 语言的前身 &…

让GPT人工智能变身常用工具-上

1.密码生成器:GPT为您创建安全密码 想象GPT作为您的个人密码生成器,负责从头到尾为您创建复杂且安全的密码。您只需要告诉他您的密码需求,比如密码的长度,是否包含大写字母、小写字母、数字或特殊字符,他会立即为您生成一个复杂但经过深度设计的密码。 例子: 我希望您…

第八届中国开源年会(COSCon'23)启动!

*海报设计师&#xff1a;朱亿钦&#xff08;居居&#xff09; 一年一度的开源盛会&#xff0c;COSCon23 第八届中国开源年会&#xff0c;将于10月28~29日&#xff0c;在四川成都市高新区菁蓉汇召开&#xff01;本次大会的主题是&#xff1a;“开源&#xff1a;川流不息、山海相…

(css)滚动条样式

(css)滚动条样式 效果&#xff1a; /*滚动条整体样式*/ ::-webkit-scrollbar {width: 2px;/*高宽分别对应横竖滚动条的尺寸*/height: 10px; } ::-webkit-scrollbar-thumb {/*滚动条里面小方块*/border-radius: 10px;width: 2px;height: 60px;background: linear-gradient(0deg,…

leetcode 78. 子集

2023.7.22 本题为回溯系列的一道标准模板题。 如果将回溯问题抽象为一棵树的话&#xff0c;那么之前的组合、分割问题都是为了找到这棵树的叶子节点&#xff0c;而子集是要找到这棵树的所有节点。 然后要注意&#xff0c;子集是无序的&#xff0c;即{1&#xff0c;2}和{2&#…

幂等性设计与实现

文章目录 前言1.全局唯一ID1.1 前端防止重复提交1.2 token机制1.3 数据库表加唯一约束 2.幂等下 ABA问题 与乐观锁2.1 乐观锁2.2 如何解决ABA问题&#xff1f; 3.分布式锁和事务3.1 分布式锁&#xff1a;3.2. 分布式事务 前言 幂等性&#xff08;Idempotence&#xff09;是一个…

导航、开源镜像、Prompt ( AI 提示词 )、AI工具集、chatgpt镜像

1、导航 网站 众多网址导航中&#xff0c;哪个最好&#xff1f;理由是什么&#xff1f; &#xff1a;https://www.zhihu.com/question/19899559 除了百度&#xff0c;其他搜索引擎&#xff1a; 综合类搜索导航(Anywhere Anything)&#xff1a;http://lackar.com/aa/ 渗透师 导…

开源QianWei搭建音乐网站,并实现公网连接

开源QianWei搭建音乐网站&#xff0c;并实现公网连接 1、前言2、本地网页搭建2.1环境使用2.2 支持组建选择2.3 网页安装 3、本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4、公网访问测试5、结语 1、前言 音乐是我们生活和工作中不可或缺的调剂&#xff0c;它能让我们心…

二,jmeter的简介还有一些参数的说明

文章目录 一、jmeter简介及安装1. 简介2. 安装 二、jmeter设置语言三、jmeter文件路径说明四、编写jmeter脚本五、乱码的处理&#xff1a;1. 请求内容出现乱码处理方法2. 响应内容出现乱码处理方法 一、jmeter简介及安装 1. 简介 Apache 托管的开源java工具接口测试、自动化测…

Sublime Text 设置中文

文章目录 1. Subime Text 官网2. 中文设置 1. Subime Text 官网 https://www.sublimetext.com/ 2. 中文设置 打开 sublime&#xff0c;ctrl shift p&#xff0c;在对话框搜索 Install Package Control&#xff0c;点击 会弹出一个消息框&#xff0c;表示插件列表加载完成…

【每日一题】42. 接雨水

【每日一题】42. 接雨水 42. 接雨水题目描述解题思路 42. 接雨水 题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输…

【STM32CubeMX】HC_SR04模块测距

前言 本文章介绍了基于STM32F103的HAL库&#xff0c;完成对HC_SR04超声波模块测距的基本思路和工程案例。 环境 STM32F103C6T6系统板&#xff0c;72MHz主频基于STM32CubeMX生成的HAL库代码硬件连接&#xff1a; PB12 — Echo(HC_SR04)&#xff0c;PB13 — Trig(HC_SR04)PB9 —…

第二十二章:Non-local Neural Networks ——非局部神经网络

0.摘要 卷积和循环操作都是一次处理一个局部邻域的基本构建模块。在本文中&#xff0c;我们提出了非局部操作作为捕捉长程依赖关系的通用构建模块族。受计算机视觉领域经典的非局部均值方法[4]的启发&#xff0c;我们的非局部操作将一个位置的响应计算为所有位置特征的加权和。…

LiveNVR监控流媒体Onvif/RTSP功能-拉转Onvif/RTSP/RTMP/FLV/HLS直播流流媒体服务视频广场页面集成视频播放集成说明

LiveNVR拉转Onvif/RTSP/RTMP/FLV/HLS直播流流媒体服务视频广场页面集成视频播放集成说明 1、视频页面集成1.1、关闭接口鉴权1.2、视频广场页面集成1.2.1、隐藏菜单栏1.2.2、隐藏播放页面分享连接 1.3、其它页面集成 2、播放分享页面集成2.1、获取 iframe 代码2.2、html 集成ifr…