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

news2025/1/10 21:01:04

文章目录

  • 索引实现
    • 索引存储
    • 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字段,而是使用生日(年月日)。(因为年龄是经常变化的字段,而生日不会变

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

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

相关文章

手把手带你创建一个自己的GPTs

大家好&#xff0c;我是五竹。 最近GPT又进行了大升级&#xff0c;这一下又甩了国内AI几条街&#xff0c;具体更新了哪些内容之前的一篇文章中其实已经说过了&#xff1a;ChatGPT 王炸升级&#xff01;更强版 GPT-4 上线&#xff01; 其中最重要的一点就是支持自定义GPT&…

【博士每天一篇文献-算法】Imposing Connectome-Derived Topology on an Echo State Network

阅读时间&#xff1a;2023-11-5 1 介绍 年份&#xff1a;2022 作者&#xff1a;Jacob Morra, Mark Daley 西部大学 期刊&#xff1a;2022 International Joint Conference on Neural Networks (IJCNN) 引用量&#xff1a;3 研究了果蝇连接图的拓扑结构对混沌时间序列预测中回…

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】 一、漏洞描述二、漏洞影响三、漏洞危害四、FOFA语句五、漏洞复现1、手动复现yaml pocburp发包 2、自动化复现小龙POC检测工具下载地址 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传…

代码随想录算法训练营第18天|513. 找树左下角的值 112. 路径总和 113.路径总和ii 106.从中序与后序遍历序列构造二叉树

JAVA代码编写 513. 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7提示: 二叉树的节点个…

Vue.js 学习总结(3)—— vite 打包图片时报错 Rollup failed to resolve import...

问题 图片依赖&#xff1a; Vite 打包前端项目时图片无法引入&#xff0c;报如下错误&#xff1a; ERROR [vite]: Rollup failed to resolve import "%7BlibeiDanmuKongmu%7D" from "D:/java/workspace/jeecgboot-vue3/src/views/funeral/tombInfo/area.vue?…

《数据结构、算法与应用C++语言描述》-队列的应用-工厂仿真

工厂仿真 完整可编译运行代码见&#xff1a;Github::Data-Structures-Algorithms-and-Applications/_19Factory simulation/ 问题描述 一个工厂有m台机器。工厂的每项任务都需要若干道工序才能完成。每台机器都执行一道工序&#xff0c;不同的机器执行不同的工序。一台机器一…

13年测试老鸟,稳定性测试要点+性能监控关键指标分析(详细)

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

FlinkSQL聚合函数(Aggregate Function)详解

使用场景&#xff1a; 聚合函数即 UDAF&#xff0c;常⽤于进多条数据&#xff0c;出⼀条数据的场景。 上图展示了⼀个 聚合函数的例⼦ 以及 聚合函数包含的重要⽅法。 案例场景&#xff1a; 关于饮料的表&#xff0c;有三个字段&#xff0c;分别是 id、name、price&#xff0…

录制GIF图,动态图

软件下载链接&#xff1a; https://www.cockos.com/licecap/ 参考链接&#xff1a; https://chat.xutongbao.top/

<C++> stack queue模拟实现

目录 前言 一、stack的使用 1. 接口说明 2. 例题 二、模拟实现stack 三、queue的使用 四、模拟实现queue 五、deque 总结 前言 LIFO stack 1. 栈是一种容器适配器&#xff0c;专门设计用于在后进先出上下文&#xff08;后进先出&#xff09;中运行&#xff0c;其中元素仅从容器…

Linux之基本指令操作

1、whoami whoami&#xff1a;查看当前账号是谁 2、who who&#xff1a;查看当前我的系统当中有哪些用户&#xff0c;当前有哪些人登录了我的机器 3、 pwd pwd&#xff1a;查看我当前所处的目录&#xff0c;就好比Windows下的路径 4、ls ls&#xff1a;查看当前目录下的文件信…

搭建Docker

一、概念 云服务器大家肯定不陌生了&#xff0c;相比较传统物理服务器来说他的价格&#xff0c;个性化的配置服务&#xff0c;节省了很多的运维成本&#xff0c;越来越多的企业以及个人开发者更加的青睐于云服务器。有了属于自己的服务器就可以部署搭建自己个人网站了&#xf…

【博士每天一篇文献-模型】A mechanistic model of connector hubs, modularity and cognition

阅读时间&#xff1a;2023-11-10 1 介绍 年份&#xff1a;2018 作者&#xff1a;Maxwell A. Bertolero, B. T. Thomas Yeo 期刊&#xff1a; nature human behaviour 引用量&#xff1a;180 2 创新点 作者提出了一个机制模型&#xff0c;解释了连接中枢的功能以及其对认知表…

深度学习1【吴恩达】

视频链接&#xff1a;1.5 关于这门课_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1FT4y1E74V?p5&spm_id_frompageDriver&vd_source3b6cdacf9e8cb3171856fe2c07acf498 视频中吴恩达老师所有的话语收录&#xff1a; 机器学习初学者-AI入门的宝典 (ai-start.c…

知识蒸馏概述及开源项目推荐

文章目录 1.介绍2.知识2.1 基于响应的知识&#xff08;response-based&#xff09;2.2 基于特征的知识(feature-based)2.3 基于关系的知识(relation-based) 3.蒸馏机制3.1 离线蒸馏3.2 在线蒸馏3.3 自蒸馏 4.教师-学生架构5.蒸馏算法5.1 对抗性蒸馏&#xff08;Adversarial Dis…

计算机组成原理第四章(存储系统)(一)

一、存储器概述 1.分类&#xff1a; 存取方式&#xff1a;随机存储器&#xff08;RAM&#xff09;、顺序存储器&#xff08;SAM&#xff09;、直接存储器&#xff08;DAM&#xff09; 存储介质&#xff1a;磁性材料存储器、半导体存储器、光存储器 功能和存取速度&#xff1a; …

docker stop slow 解决

验证 NanoMQ stop slow 的问题 daemon 和非 daemon 两种方式 docker stop 都很慢 疑问是默认情况下&#xff0c;SIGTERM 会被处理。 模拟 docker 内发送 SIGTERM 信号 # The default signal for kill is TERM # pkill will send the specified signal (by defau…

常微分方程

什么是常微分方程&#xff1a; 未知函数为单变量(一元)函数 例1 设有温度为100摄氏度的物体放置在20摄氏度的空气冷却&#xff0c;求物体温度随时间 变化 的规律。 解&#xff1a;设t时刻物体温度为T 对两边求共积分 设比例系数为k>0 令C, 微分方程&#xff1a; 联系着…

算法导论笔记4:散列数 hash

一 了解一些散列的基本概念&#xff0c;仅从文字角度&#xff0c;整理了最基础的定义。 发现一本书&#xff0c;《算法图解》&#xff0c;微信读书APP可读&#xff0c;有图&#xff0c;并且是科普性质的读物&#xff0c;用的比喻很生活化&#xff0c;可以与《算法导论》合并起…

论文笔记--Baichuan 2: Open Large-scale Language Models

论文笔记--Baichuan 2: Open Large-scale Language Models 1. 文章简介2. 文章概括3 文章重点技术3.1 预训练3.1.1 预训练数据3.1.2 模型架构 3.2 对齐3.2.1 SFT3.2.2 Reward Model(RM)3.2.3 PPO 3.3 安全性 4. 文章亮点5. 原文传送门 1. 文章简介 标题&#xff1a;Baichuan 2…