第23章(下)_索引原理剖析

文章目录

  • 索引实现
    • 索引存储
    • B+树
    • 为什么 MySQL InnoDB 选择 B+ 树作为索引的数据结构?
    • B+ 树层高问题
    • 关于自增id
    • 最左匹配原则
    • 覆盖索引
    • 索引下推
    • innodb体系结构
      • Buffer pool
      • change buffer
  • 总结

索引实现

索引存储

innodb 由段、区、页组成。段分为数据段、索引段、回滚段等。
区大小为 1 MB(一个区由 64 个连续页构成)。页的默认值为 16KB。页为逻辑页,磁盘物理页大小一般为 4K 或者 8K。
为了保证区中的页的连续,存储引擎一般一次从磁盘中申请4~5 个区。
在这里插入图片描述
页是 innodb 磁盘管理的最小单位;默认16K,可通过innodb_page_size 参数来修改。B+ 树的一个节点的大小就是该页的值。
索引存储

B+树

B+树全称:多路平衡搜索树,是为了减少磁盘访问次数。用来组织磁盘数据,以页为单位,物理磁盘页一般为 4K,innodb 默认页大小为16K;对页的访问是一次磁盘 IO,缓存中会缓存常访问的页。

innodb中的B+树的特征:

(1)多路平衡搜索树。

(2)所有的叶子节点都在同一层。

(3)并且叶子节点构成一个双向链表。

(4)节点的大小是固定的,都为数据页大小(16K)。

(5)非叶子节点只记录索引信息,叶子节点记录数据信息。

在这里插入图片描述

为什么 MySQL InnoDB 选择 B+ 树作为索引的数据结构?

∘ \circ 降低磁盘IO:B+树的非叶节点只包含键,而不包含真实数据,因此每个节点可以存储更多的记录个数。所以B+树的高度更低,访问时所需要的IO次数更少。此外,由于每个节点存储的记录数更多,所以对访问局部性原理的利用更好,缓存命中率更高。相比之下,红黑树在磁盘上的存储方式相对随机,导致磁盘 I/O 操作更频繁。哈希表则不适合直接存储在磁盘上,因为哈希表需要通过哈希函数计算位置,无法充分利用磁盘的顺序读写特性。

∘ \circ 范围查询:B+树的叶子节点间构成一个双向链表,范围查询只需要对链表进行遍历即可。相比之下,红黑树和哈希表无法提供高效的范围查询支持。红黑树虽然能够支持有序访问,但在范围查询时需要遍历整个树,性能较差。而哈希表是基于哈希函数进行快速查找的,适用于单个键值查询,但对于范围查询则需要扫描整个表格,效率较低。

B+ 树层高问题

B+ 树的一个节点对应一个数据页;B+ 树的层越高,那么要读取到内存的数据页越多,IO 次数越多;
innodb 一个节点 16KB;
假设:
key 为 10byte 且指针大小 6byte,假设一行记录的大小为1KB;那么一个非叶子节点可存下 16 KB / 16 byte=1024 个
(key+point);每个叶子节点可存储 1024 行数据;
结论:
2层B+树叶子节点1024个,可容纳最大记录数为: 1024 * 16 = 16384;
3层B+树叶子节点1024 * 1024,可容纳最大记录数为:1024 * 1024 * 16 = 16777216;
4层B+数叶子节点1024 * 1024 * 1024,可容纳最大记录数为:1024 * 1024 * 1024 * 16 = 17179869184;

关于自增id

超过类型最大值会报错;
类型 bigint 范围:在这里插入图片描述
假设采用 bigint,1 秒插入 1 亿条数据,大概需要 5849 年才会用完索引;

最左匹配原则

主要针对组合索引。从左到右依次匹配,遇到模糊匹配(>、<、between、like等)时就停止匹配;如果没有第一个索引也停止匹配。

示例:

DROP TABLE IF EXISTS `left_match_t`;
CREATE TABLE `left_match_t` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(255) DEFAULT NULL,
	`cid` INT(11) DEFAULT NULL,
	`age` SMALLINT DEFAULT 0,
	PRIMARY KEY (`id`),
	KEY `name_cid_idx` (`name`, `cid`)
)ENGINE = INNODB AUTO_INCREMENT=0 DEFAULT CHARSET = utf8;


INSERT INTO `left_match_t` (`name`, `cid`, `age`)
VALUES
	('FLY', 10001, 12),
	('fly', 10002, 13),
	('cc', 10003, 14),
	('ff', 10004, 15)

SHOW INDEX FROM `left_match_t`;

# 作用优化器
EXPLAIN SELECT * FROM `left_match_t` WHERE `name` = 'mark';

# 优化器
EXPLAIN SELECT * FROM `left_match_t` WHERE `cid` = 1 AND `name` = 'mark';

# 不会走索引
EXPLAIN SELECT * FROM `left_match_t` WHERE `cid` = 1;

覆盖索引

覆盖索引是一种数据查询方式,主要针对辅助索引。从辅助索引中就能找到数据,而不需通过聚集索引查找;利用辅助索引树高度一般低于聚集索引树, 可以较少的磁盘 IO。

也就是,如果查询的字段是辅助索引,那么查询过程中就不需要回表查询,直接使用辅助索引B+树就可以查询到数据。

示例:

DROP TABLE IF EXISTS `covering_index_t`;
CREATE TABLE `covering_index_t` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(255) DEFAULT NULL,
	`cid` INT(11) DEFAULT NULL,
	`age` SMALLINT DEFAULT 0,
	`score` SMALLINT DEFAULT 0,
	PRIMARY KEY (`id`),
	KEY `name_cid_idx` (`name`, `cid`)
)ENGINE = INNODB AUTO_INCREMENT=0 DEFAULT CHARSET = utf8;


INSERT INTO `covering_index_t` (`name`, `cid`, `age`, `score`)
VALUES
	('FLY', 10001, 12, 99),
	('fly', 10002, 13, 98),
	('cc', 10003, 14, 97),
	('ff', 10004, 15, 100);

SHOW INDEX FROM `covering_index_t`;

-- 需要回表查询
SELECT * FROM `covering_index_t` WHERE `name` = 'FLY';

-- 查询字段是辅助索引(`name`, `cid`, `id`),不需要回表查询
SELECT `name`, `cid`, `id` FROM `covering_index_t` WHERE `name` = 'FLY';

总结:

在使用中,尽量不要使用select * …来获取数据;因为里面有些字段可能没有创建索引,没有创建索引就需要回表查询,这会增加磁盘IO。所以,在select中尽量写所需的字段。

索引下推

具体原理查看mysql索引下推。

innodb体系结构

在这里插入图片描述

Buffer pool

Buffer Pool是一个用于存储数据和索引页的内存区域,它以固定大小的页为单位进行管理,通常以16KB为一页。它的作用是采用 LRU 算法将最常用的数据页(热点数据)保留在内存中,以减少对磁盘IO的需求。当数据被查询或更新时,首先通过自适应hash索引查询数据是否在buffer pool中;如果数据不在,则通过mmap将磁盘数据映射到buffer pool中;如果数据存在buffer pool中就直接操作。
在这里插入图片描述
buffer pool 用于缓存若干数据页,降低磁盘IO次数。

change buffer

Change buffer 缓存非唯一索引的数据变更(DML操作),Change buffer 中的数据将会异步merge 到磁盘当中。当执行更新操作(如插入、更新、删除)时,InnoDB会将修改的数据页(包括数据和索引页)首先写入到Change Buffer中,而不是直接写入磁盘。Change Buffer是一个内存中的缓冲区,用于暂时存储待写入的修改操作。
在这里插入图片描述
change buffer目的是将DML数据合并到buffer pool。
在这里插入图片描述
(1)free list 组织 buffer pool 中未使用的缓存页;

(2)flush list 组织buffer pool 中脏页,也就是待刷盘的页;

(3)lru list 组织 bufferpool 中冷热数据,当 buffer pool 没有空闲页,将从 lru list 中最久未使用的数据进行淘汰。

总结

  1. 一定要确定一个主键索引的原因是:主键索引对应的是聚集索引B+树,所有的数据要存储在主键对应的B+树中。
  2. innodb中的B+树 非叶子节点只存储索引信息,叶子节点存储具体数据信息;叶子节点之间互相连接,方便范围查询。每个索引对应一个B+树。
  3. MySQL的索引实现使用B+树而不是使用其他树的原因是降低磁盘IO以及方便范围查询。
  4. 覆盖索引是一种数据查询方式,主要针对辅助索引;直接通过辅助索引B+树就能获取查询的值,而无需通过回表查询。
  5. 根据覆盖索引的原理,在select中尽量写所需要的字段,不要写select * … 。
  6. 没有索引下推机制时,server层向存储引擎层请求数据,在server层根据索引条件判断进行数据过滤。有了索引下推机制,将索引条件下推到存储引擎中过滤数据,最终由存储引擎进行数据汇总返回给server层。
  7. B+树的页是通过mmap映射到磁盘的数据块,以此来组织数据。
  8. MySQL通过自适应hash索引快速判断某个页是否在缓存中(buffer pool)。
  9. MySQL中的explain用于制作执行计划,作用在优化器阶段。
  10. 工作中不要使用age字段,而是使用生日(年月日)。(因为年龄是经常变化的字段,而生日不会变

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

摊位展示预约小程序的作用有哪些

无论市场还是街边&#xff0c;小摊小贩往往很多&#xff0c;组成了丰富多彩的线下购物环境&#xff0c;而在实际发展中&#xff0c;摊位的需求度很高&#xff0c;但由于种种原因&#xff0c;导致在实际发展中&#xff0c;也有一定难题&#xff1a; 1、摊位预约难、信息查看难 …

js 求数组中的对象某个属性和

可以直接看下效果 代码&#xff1a; <script>let list [{num: 1,price: 10,},{num: 2,price: 10,},{num: 3,price: 10,},{num: 4,price: 10,},]// for循环 求总数和 num的和let num 0for (let i 0; i < list.length; i) {num list[i].num}console.log(第一种&am…

pytorch代码实现注意力机制之Flatten Attention

Flatten Attention 介绍&#xff1a;最新注意力Flatten Attention&#xff1a;聚焦的线性注意力机制构建视觉 Transformer 在将 Transformer 模型应用于视觉任务时&#xff0c;自注意力机制 (Self-Attention) 的计算复杂度随序列长度的大小呈二次方关系&#xff0c;给视觉任务…

Leetcode-144 二叉树的前序遍历

递归方法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

局部路由守卫component守卫

局部路由守卫component守卫 component守卫&#xff08;beforeRouteEnter、beforeRouteLeave&#xff09; 代码位置&#xff1a;在路由组件中&#xff0c;代码是写在component当中的&#xff08;XXX.vue&#xff09;beforeRouteEnter、beforeRouteLeave都有三个参数&#xff1…

2023年加氢工艺证考试题库及加氢工艺试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年加氢工艺证考试题库及加氢工艺试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机出的加氢…

Linux操作系统使用及C高级编程-D2软件包管理

有两种类型的软件包&#xff1a;二进制软件包(deb)和源码包(deb-src) 二进制软件包(Binary Packages)&#xff1a;包含可执行文件、库文件、配置文件、main/info页面、版权声明和其他文档 源码包(Source Packages)&#xff1a;包含软件源代码、版本修改说明、构建指令及编译工…

科研检测机构服务预约小程序的效果如何

科研检测机构涵盖的业务比较广&#xff0c;比如水质检测、农产品检测、食品检测等&#xff0c;对相关从业者来说&#xff0c;可能需要频繁使用这些业务&#xff0c;或者个人偶尔需要一些东西检测。 对用户和检测机构来说&#xff0c;由于行业的特殊性&#xff0c;在实际发展中…

男科医院服务预约小程序的作用是什么

医院的需求度从来都很高&#xff0c;随着技术发展&#xff0c;不少科目随之衍生出新的医院的&#xff0c;比如男科医院、妇科医院等&#xff0c;这使得目标群体更加精准&#xff0c;同时也赋能用户可以快速享受到服务。 当然相应的男科医院在实际经营中也面临痛点&#xff1a;…

XC1010非隔离型、低成本的PWM功率开关、AC-DC 220V转5V 200mA小电流芯片

XC1010是一款非隔离型、高集成度且低成本的PWM功率开关&#xff0c;适用于降压型和升降压型电路。 XC1010采用高压单晶圆工艺&#xff0c;在同一片晶圆上集成有 500V 高压 MOSFET 和采用开关式峰值电流模式控制的控制器。在全电压输入的范围内可以保证高精度的 5V 默认…

MySQL---存储过程

存储过程的相关概念 是一组为了完成特定功能的sql语句的集合&#xff0c;类似于函数 写好了一个存储过程之后&#xff0c;我们可以像函数一样随时调用sql的集合。 复杂的&#xff0c;需要很多sql语句联合执行完成的任务 存储过程再执行上比sql语句的执行速度更快&#xff0c…

24 _ 二叉树基础(下):有了如此高效的散列表,为什么还需要二叉树?

上一节我们学习了树、二叉树以及二叉树的遍历,今天我们再来学习一种特殊的二叉树,二叉查找树。二叉查找树最大的特点就是,支持动态数据集合的快速插入、删除、查找操作。 我们之前说过,散列表也是支持这些操作的,并且散列表的这些操作比二叉查找树更高效,时间复杂度是O(…

玩转Linux基本指令

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;牢记Linux的基本指令。 > 毒鸡汤&#xff1a;挫…

ROS话题(Topic)通信:通信模型、Hello World与拓展

文章目录 一、话题通讯模型二、Topic Hello World2.1 创建并初始化功能包2.2 确定Topic名称及消息格式2.3 实现发布者与订阅者&#xff08;C版&#xff09;2.4 实现发布者与订阅者&#xff08;Python版&#xff09;2.5 关于Topic Hello World的注意 拓展1&#xff1a;devel下其…

深度学习 python opencv 火焰检测识别 火灾检测 计算机竞赛

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

【Linux】Linux 中关于文件和文件夹的常用命令

Linux 中关于文件和文件夹的常用命令 讲解 Linux 常用命令的文章已经非常多了&#xff0c;而且有的文章也说的非常清楚详细。我们可能不会记住所有的命令&#xff0c;但对于工作中常用的命令应该熟记于心&#xff0c;最好的方式就是多多实践。 我们可以直接或者通过虚机的方式…

全网最细,Apipost接口自动化测试-关联配置,老鸟带你上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 在接口自动化测试…

【C++对象模型】构造函数II

构造函数语意学 》》构造函数语意学I—默认构造函数的构造操作《《 》》构造函数语意学II—拷贝构造函数的构造操作《《 》》构造函数语意学III—程序转化语意学《《 拷贝构造函数的构造操作 有三种情况&#xff0c;会以一个object的内容作为另一个class object的初值。 1.…

Ansible自动化运维工具及模块

目录 一、Ansible 1.ansible简介 2、ansible的特性 二、ansible的部署 1&#xff09;管理端安装ansible 2&#xff09;配置主机清单 3&#xff09;配置密钥对验证 三、ansible命令块模块 1&#xff09;command模块 2&#xff09;shell模块 3&#xff09;cron模块 4)…

MySQL如何查找删除重复行?

如何查找重复行 第一步是定义什么样的行才是重复行。多数情况下很简单&#xff1a;它们某几列具有相同的值。本例采用这种定义&#xff0c;或许你对“重复”的定义得很复杂&#xff0c;你需要对sql做些修改。本例要用到的数据样本&#xff1a; create table test(id int not …