InnoDB索引结构

news2024/9/29 6:01:00

文章目录

  • 索引数据结构
    • 聚集索引
    • 非聚集索引
  • 索引维护
    • 顺序插入和随机插入
    • 为什么预留空间
  • 索引构建过程
  • 页的合并拆分

索引数据结构

https://dev.mysql.com/doc/refman/8.4/en/innodb-physical-structure.html
除了空间索引(spatial index)使用R-tree之外,InnoDB索引数据结构都是B+树。每个节点都是一个Page,Page是InnoDB存储记录的最小单位。非叶子节点存储指向子节点的 key 和指针的值。叶子节点存储记录和指向相邻叶节点的指针。索引记录存储在其B+树的叶子节点Page中。索引页的默认大小为16KB。页的大小由MySQL实例初始化时的设置项innodb_page_size设置决定。

聚集索引

每个InnoDB表都有一个特殊的索引,称为聚集索引。聚集索引的功能不单单只是索引,更重要的是,它用于存储引擎为InnoDB的表的所有数据行。

一个表最多只能有一个聚集索引,下面是聚集索引的选取规则:

  1. 当有主键时,则将主键用作聚集索引
  2. 当没有主键时,使用第一个NOT NULL UNIQUE索引作为聚集索引。
  3. 如果以上都没有,InnoDB会在包含行ID值的合成列上生成一个名为GEN_CLUST_INDEX的隐藏聚集索引

在这里插入图片描述

聚集索引按 key 也就是主键值顺序存储记录,父节点的 key 会在子节点复制一份,并且每个叶节点连接到其相邻的叶节点。这有以下几个好处:

  1. 双向链表允许在页之间快速移动,便于在不同页之间进行导航。这对于遍历和访问数据时非常高效,因为可以在链表中向前和向后移动。
  2. 在处理行插入和删除时,双向链表可以快速找到需要更新的页。这对于页的合并、分裂和重用都非常有利。
  3. 执行范围查询不需要扫描整个树。它所需要做的就是找到包含最小值的叶节点,然后加载下一个叶节点,以此类推,直到到达包含最大值的叶结点。

如果以随机的 key 顺序插入记录,会有性能问题。例如,添加一条键为13的记录,MySQL会将该记录保存在第8页。但是,当您使用 9 作为 key 添加记录时,会导致第7页进行拆分。在这种情况下,MySQL会在页之间移动记录并影响性能。

非聚集索引

辅助索引类似于聚集索引,区别在于,它不在叶子节点中存储数据行,而只存储辅助索引的索引 key 和聚集索引的 key (通常是主键)来查找记录:
在这里插入图片描述
辅助索引 key 的顺序和聚集索引 key 的顺序通常不相同,因此进行范围查询不如聚集索引有效。此外,由于辅助索引将存储聚集索引 key ,聚集索引 key 的大小将影响辅助索引的大小。

索引维护

MySQL不会填满整个页的空间;相反,它会为以后的修改留下空间,比如上图第6页。根据MySQL 5.7参考手册:

当新记录插入到InnoDB聚集索引中时,InnoDB会尝试留出1/16的页空间,以便将来插入和更新索引记录。如果按顺序插入索引记录,升序或降序,则生成的索引页的大小约为15/16。如果记录以随机顺序插入,则页面的大小1/2 ~ 15/16。

顺序插入和随机插入

插入数据的顺序取决于多个因素,包括表的类型、存储引擎、索引设计以及具体的插入操作。以下是一些关键情况:

  1. 顺序插入
    自增主键:使用自增(AUTO_INCREMENT)字段时,插入的记录通常是顺序的。例如,当你插入新的行时,它们会根据自增值的顺序添加到表中。
    没有竞争的插入:在没有并发插入的情况下,数据通常按插入的顺序存储。
    InnoDB 存储引擎:InnoDB 使用聚簇索引(Clustered Index),数据行按照主键顺序存储,因此在自增主键的情况下,数据会顺序插入。
  2. 随机插入
    非自增主键:如果你使用非自增主键(如 UUID 等),插入的记录可能会在不同的位置随机存储。
    并发插入:在高并发环境下,多个并发插入可能会导致数据在存储中的位置不再是顺序的。
    使用特定的插入策略:如果你在插入时指定了一个具体的值(而不是自增),并且这些值是随机生成的,那么数据将随机分布在表中。
    表类型:
    对于某些表类型(如 MyISAM),如果插入数据时没有索引,数据可能会顺序插入。然而,一旦有索引,插入可能会导致随机位置的更新。
  3. 影响因素
    事务:在事务中,数据的插入顺序可能会因为锁机制而影响。
    索引更新:当插入新记录时,索引的更新可能导致数据在存储中的位置分散。
    数据分区:如果使用了数据分区,插入数据的顺序也可能受到影响。

总结
顺序插入:通常发生在使用自增主键且没有并发插入的情况下。
随机插入:发生在使用非自增主键、并发插入或特定插入策略的情况下。

为什么预留空间

在 MySQL 中,页是存储引擎用于管理数据的基本单位。预留空间在 MySQL 页管理中起着关键作用。预留空间是为了提高性能和效率,它能够减少页分裂,提高插入和更新性能,优化空间利用率,并提升整体数据库的并发处理能力和查询性能。以下是一些主要原因:

  1. 减少页分裂频率
    当页满时,如果需要插入新数据,存储引擎会执行页分裂,导致性能下降。预留空间可以减少这种情况的发生,从而减少页分裂的频率。
  2. 提高插入性能
    在批量插入数据时,预留空间可以容纳更多的数据,减少因频繁分裂页而导致的性能开销。
  3. 优化更新操作
    行更新:当更新现有行的大小时,例如增加字符串长度,预留空间可以避免频繁的页移动和分裂,减少锁争用和提高并发性能。
  4. 提高空间利用率
    预留空间有助于维持高效的空间利用率,避免频繁的页合并和碎片化,保持数据的紧凑存储。
  5. 支持动态行格式
    动态扩展:例如,InnoDB 支持动态行格式,长行数据可以存储在不同的页中,预留空间有助于管理这些指针和数据的存储。
  6. 减轻锁争用
    提高并发性:预留空间可以减少因页分裂导致的锁争用,从而提高数据库的并发处理能力。
  7. 优化读性能
    缓存效果:预留的空间可以提高页的缓存效果,减少磁盘 IO,从而提高查询性能。

索引构建过程

https://dev.mysql.com/doc/refman/8.4/en/sorted-index-builds.html
InnoDB在创建或重建B+树索引时执行批量加载。这种索引创建方法被称为排序索引构建。innodb_fill_factor变量定义了在排序索引构建期间填充的每个B+树页面上的空间百分比,剩余空间保留用于未来的索引增长。innodb_fill_factor设置为100时,聚集索引页中有1/16的空间可用于未来的索引增长。

索引构建有三个阶段:

  1. 第一阶段,扫描聚集索引,生成索引项并将其添加到排序缓冲区。当排序缓冲区已满时,索引项将被排序,然后写入临时中间文件
  2. 第二阶段,第一阶段执行了一次或多次后,对写入的临时中间文件中的所有索引项执行合并排序
  3. 第三阶段,将排序后的索引项插入到B+树中;这个过程是多线程的

页的合并拆分

页满率:页的数据量占总数据容量的百分比

如果删除行或通过UPDATE操作缩短行时索引页的页满率低于MERGE_THRESHOLD值,InnoDB将尝试将索引页与相邻索引页进行合并。默认的MERGE_THRESHOLD值为50,最小MERGE_THRESHOLD值为1,最大值为50。

当索引页的页满率降至默认MERGE_THRESHOLD设置的50%以下时,InnoDB会尝试将索引页与相邻页面合并。如果两个页面都接近50%满,则页面合并后很快就会发生页面拆分。如果这种合并-拆分行为频繁发生,可能会对性能产生不利影响。为了避免频繁的合并拆分,您可以降低MERGE_THRESHOLD值,以便InnoDB尝试以较低的容量百分比进行页合并。以较低的页满率合并页会在索引页面中留下更多空间,并有助于减少页的合并拆分行为。

索引页的MERGE_THRESHOLD可以为表或单个索引定义。为单个索引定义的MERGE_THRESHOLD值优先于为表定义的MERGE_THRESHORD值。如果未定义,则MERGE_THRESHOLD值默认为50。


参考资料:

  1. https://dev.mysql.com/doc/refman/8.4/en/innodb-physical-structure.html
  2. https://medium.com/@genchilu/a-brief-introduction-to-cluster-index-and-secondary-index-in-innodb-9b8874d4da6a

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

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

相关文章

RTMP、RTSP直播播放器的低延迟设计探讨

技术背景 没有多少开发者会相信RTMP或RTSP播放器,延迟会做到150-300ms内,除非测试过大牛直播SDK的,以Android平台启动轻量级RTSP服务和推送RTMP,然后Windows分别播放RTSP和RTMP为例,整体延迟如下: 大牛直播…

FastAPI 第六课 -- 请求和响应

目录 一. 前言 二. 请求数据 2.1. 查询参数 2.2. 路径参数 2.3. 请求体 三. 响应数据 3.1. 返回 JSON 数据 3.2. 返回 Pydantic 模型 3.3. 请求头和 Cookie 四. 重定向和状态码 五. 自定义响应头 一. 前言 在 FastAPI 中,请求(Request&#…

【web安全】——信息收集

一、收集域名信息 1.1域名注册信息 工具:站长之家 whois查询 SEO综合查询 1.2子域名收集 原理:字典爆破,通过字典中的各种字符串与主域名拼接,尝试访问。 站长之家 直接查询子域名 ip138.com https://phpinfo.me/domain/ …

【源码+文档+调试讲解】美食推荐系统Python

摘 要 随着我国经济的高速发展与人们生活水平的日益提高,人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下,人们更趋向于足不出户解决生活上的问题,豆果美食推荐系统展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c…

第十四届蓝桥杯真题Python c组F.棋盘(持续更新)

博客主页:音符犹如代码系列专栏:蓝桥杯关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 【问题描述】 小蓝拥有 n n 大小的棋盘,一开始棋盘上全都…

【韩顺平Java笔记】第2章:Java概述

按视频的标号来对应小标题,自用学习笔记 文章目录 5. 内容梳理6. 程序举例6.1 什么是程序 7. Java故事7.1 Java诞生小故事7.2 Java技术体系平台 8. Java特性8.1 Java重要特点 9. sublime10. jdk介绍10.1 Java运行机制及运行过程10.1.1 Java虚拟机(JVM&a…

基于ASRPRO的语音应答

做这个的起因是为了送女朋友,而且这东西本身很简单,所以在闲暇之余尝试了一下。 这个工程很简单,只通过对ASRPRO进行编程即可。 先看效果。(没有展示所有效果,后续会列出来所有对话触发) 语音助手示例1 语音…

AI驱动TDSQL-C Serverless 数据库技术实战营-与AI的碰撞

目录 一、简介 二、实验介绍 三、结果展示 四、实操指导 4.1 系统设计 4.2 环境搭建(手把手教程) 4.3 应用构建 4.4 效果展示 4.5 踩坑避雷总结 五、清理资源 5.1 删除TDSQL-C Serverless 5.2 删除 HAI 算力 六、实验总结归纳 一、简介 本…

Netty系列-5 Netty启动流程

背景 Netty程序有固定的模板格式,以ServerBootstrap为例: public class NettyServer {public void start(int port) {ServerBootstrap serverBootstrap new ServerBootstrap();EventLoopGroup boosGroup new NioEventLoopGroup(1);EventLoopGroup workGroup ne…

番外篇 | 应对遮挡挑战,北航提出新型模型YOLOv5-FFM表现优异

前言:Hello大家好,我是小哥谈。在本文中,作者提出了一种改进的轻量级YOLOv5-FFM模型来解决行人检测遮挡问题。为了实现目标,作者在YOLOv5模型框架基础上进行了改进,并引入了Ghost模块和SE模块。此外,作者还设计了一个局部特征融合模块(FFM)来处理行人检测中的遮挡问题。…

【题解】2022ICPC杭州-K

翻译 原题链接   简述一下就是每次询问重新定义一个字母排序表&#xff0c;问在这个顺序下n个字符串的序列的逆序数是多少。 字典树计算逆序数 先考虑初始状况下&#xff0c;即 a < b < . . . < z a<b<...<z a<b<...<z的情况下&#xff0c;逆序…

基于PI控制器的车辆行驶控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 步骤一: 确定目标与测量 4.2 步骤二: 计算误差 4.3 步骤三: 设计PI控制器 4.4 步骤四: 应用控制信号 4.5 步骤五: 反馈循环 5.完整工程文件 1.课题概述 基于PI控制器的车辆行驶控制系统是一种常…

Hive数仓操作(一)

Hive 介绍 Hive 是一个基于 Hadoop 的数据仓库工具&#xff0c;旨在简化大规模数据集的管理和分析。它将结构化数据文件映射为表&#xff0c;并提供类似 SQL 的查询功能。Hive 的数据存储在 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;中&#xff0c;使用 Hive 查询语…

使用MessagePipe实现进程间通信

1、MessagePipe介绍 可以用于.NET和Unity上面的高性能的内存/分布式消息传递管道。适用于发布/订阅模式、CQRS的中介模式、Prism中的EventAggregator、IPC&#xff08;进程间通信&#xff09;-RPC等。 支持&#xff1a; 依赖注入过滤器管道更好的事件同步/异步带键值的/无键…

信息安全工程师(26)物理安全概念与要求

前言 物理安全是网络安全体系中的重要组成部分&#xff0c;它关注于保护物理环境、设备和资源免受未经授权的访问、破坏、损坏或盗窃。 一、物理安全概念 物理安全&#xff0c;也称为实体安全&#xff0c;是指通过采取各种物理措施来保护支持网络信息系统运行的硬件&#xff08…

【Qt】Qt中的窗口坐标 信号与槽

Qt中的窗口坐标 && 信号与槽 1. Qt中的窗口坐标2. 信号与槽的概述3. 信号和槽的使用3.1 connect函数的使用3.2 查看内置信号和槽3.2 connect的参数类型不匹配问题 4. 自定义信号 && 自定义槽4.1 自定义槽4.2 自定义信号 5. 带参数的信号和槽6. 信号与槽的关联方…

leetcode_55:跳跃游戏

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输…

C#由窗体原子表溢出造成的软件闪退的问题解决方法

报错信息 由于在MS.Win32.UnsafeNativeMethods.RegisterClassEx产生了报错信息&#xff0c;但是一直向外部抛出错误但始终没有被捕捉成功&#xff0c;直到报错被UI线程捕获&#xff0c;但是仍然没有进行处理&#xff0c;所有造成WPF的应用闪退。 解析报错信息 1.从异常初始位…

Camera Raw:打开图像

在图像工作流程中&#xff0c;无论是 Raw 格式图像文件还是 JPEG、TIFF 文件&#xff0c;都可以先使用 Camera Raw 打开并调整后&#xff0c;再进入其它 Adobe 软件如 Photoshop 中进行进一步的编辑和处理。 一、打开 Raw 格式图像 1、通过 Adobe Bridge 打开 在 Adobe Bridge …

Excel插件:dd统计与排名

Excel插件&#xff1a;dd统计与排名 使用教程 专门为学校成绩统计与排名设计的插件 一、安装后如图 二、 功能介绍&#xff1a; &#xff08;一&#xff09;单科统计与排名 1、 模板说明&#xff08;单科用&#xff09; 2、 单科三分四率统计 PS&#xff1a;可以设置界值&am…