数据库之索引<保姆级文章>

news2024/11/13 9:07:22

目录:

一. 什么是索引

二. 索引应该选择哪种数据结构

三. MySQL中的页

四. 索引分类及使用


一. 什么是索引:

1. MySQL的索引是⼀种数据结构,它可以帮助数据库高效地查询、更新数据表中的数据
索引通过 ⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度
2.MySQL 索引类似于书籍的目录,通过指向数据行的位置,可以快速定位和访问表中的数据,如汉语字典的目录(索引)页,我们可以按笔画、偏旁部首、拼音等排序的目录(索引)快速查找到需要的字。
 
3. 使⽤索引的⽬的只有⼀个,就是提升数据检索的效率,在应⽤程序的运⾏过程中,查 询操作的频率远远⾼于增删改的频率

二. 索引应该选择哪种数据结构:

 下面让我们来逐个分析:

1.哈希:

如果我们使用第一种:哈希,哈希确实是一种很优秀的数据结构时间复杂度是 O(1) 查询速度非常快,但是但是MySQL并没有选择哈希,主要原因是哈希不支持持范围查找,哈希是通过哈希函数构建的,由数组+链表或红黑树组成,是通过哈希函数来定位,因此哈希不支持持范围查找。 

 


2.叉搜索树:

如果我们使用二叉搜索树的中序遍历是⼀个有序数组

但有几个问题导致它不适合用作索引的数据结构:

2.1.最坏情况下时间复杂度为O(N)

2.2.相关搜索树AVL和红⿊树 节点个数过多无法保证树高:
包括AVL和红⿊树,虽然是平衡或者近似平衡,但是毕竟是⼆叉结构
在检索数据时,每次访问某个节点的⼦节点时都会发⽣⼀次磁盘IO,⽽在整个数据库系统中,IO是性能的瓶颈,减少IO次数可以有效的提升性能,所以树高导致磁盘IO次数多是个硬伤。所以MySQL并也没有选择搜索树
 

 
3.N叉树
通过观察,相同数据量的情况下,N叉树的树⾼可以得到有效的控制,也就意味着在相同数据量的情况下可以减少IO的次数,从而提升效率。但是MySQL认为N叉树做为索引的数据结构还不够好
  
 

 
4.B+树:
B+树是⼀种经常用于 数据库和文件系统 等场合的平衡查找树, MySQL索引采用的数据结构
该数据结构解决了树高 导致磁盘IO次数多问题 ,解决了范围查询问题,由于 叶子节点保存着所有数据,性能也比较均衡。
5. B+树 特点
5.1.能够保持数据稳定有序,插入与修改有较稳定的时间复杂度
5.2.非叶子节点仅具有索引作用,不存储数据,所有叶子节点保存着所有数据
5.3.所有叶子节点构成⼀个有序链表,可以按照主键值排序的次序依次遍历全部数据

6. B+树与B树的对比
6.1.叶子节点中的数据是连续的,且相互链接,便于区间查找和搜索。
6.2.⾮叶⼦节点的值都包含在叶⼦节点中
6.3.对于B+树⽽⾔,在相同树⾼的情况下,查找任⼀元素的时间复杂度都⼀样,性能均衡



三. MySQL中的页(每一个节点就是一页):

1.为什么要使用页:
.ibd ⽂件中最重要的结构体就是Page(页),页是内存与磁盘交互的最⼩单元,默认⼤⼩为
16KB每次内存与磁盘的交互⾄少读取一页,所以在磁盘中每个页内部的地址都是连续的,之所以这样做,是因为在使⽤数据的过程中,根据局部性原理将来要使用的数据大概率与当前访问的数据在空间上是临近的 ,所以⼀次从磁盘中读取一页的数据放⼊内存中,当下次查询的数据还在这个页中时就可以从内存中直接读取,从而减少磁盘I/O提高性能。
 (解释:上面的.ibd ⽂件,是innodb储存引擎,生成的文件。)
 
 
注意:每⼀个页中即使没有数据也会使用 16KB 的存储空间,同时与索引的B+树中的节点对应,这里可以查看页大小:使用命令: show variables like ' innodb_page_size ';
 
 

 
2. 局部性原理:
是指程序在执⾏时呈现出局部性规律,在⼀段时间内,整个程序的执⾏仅限于程序中的某⼀部分。相应地,执⾏所访问的存储空间也局限于某个内存区域,局部性通常有两种形式:时间局部性和空间局部性。
时间局部性 (Temporal Locality): 如果⼀个信息项正在被访问,那么在近期它很可能还会被再次访问。
空间局部性 (Spatial Locality): 将来要⽤到的信息⼤概率与正在使⽤的信息在空间地址上是临近的。 
 

 
 
 
3.页文件头和页文件尾:
在MySQL中有多种不同类型的页,最常⽤的就是⽤来存储数据和索引的"索引⻚",也叫做"数据⻚",但不论哪种类型的⻚都会包含⻚头,和⻚尾页的主体信息使用数 据"⾏"进⾏填充,数据⻚的基本结构如下:
页文件头和页文件尾如图所示:
  
 
 
这里上一页页号和下一页页号,通过这两个属性可以把页与页之间链接起来,形成⼀个
双向链表。 
 

 
 
 
4.页主体: 
页主体部分是保存真实数据的主要区域,每当创建⼀个新页,都会⾃动分配两个行⼀个是页内最⼩行Infimun ,另⼀个是页内最⼤⾏ Supremun 这两个行并不存储任何真实信息,⽽是做为数据⾏链表的头和尾,第⼀个数据⾏有⼀个记录下⼀⾏的地址偏移量的区域 next_record 将⻚内所有数据行组成了⼀个单向链表
当向一个新页插⼊数据时,将 Infimun 连接第⼀个数据行,最后⼀⾏真实数据行连接
Supremun ,这样数据行就构建成了⼀个单向链表,更多的行数据插⼊后,会按照主键从⼩到⼤的顺序进行链接
此时新 的结构如下所示
  
 
 
5.页目录 :
 
1.说明:⼀个⻚有16KB,通常会存在数百数据,每次都要遍历数百⾏,⽆法满⾜⾼效查
询,为了提⾼查询效率,InnoDB采⽤⼆分查找来解决查询效率问题  
 2. 因此加入 页目录 这个结构:
将页内包括头行、尾⾏在内的所有⾏进⾏分组,约定头行单独为⼀组,其他每个组最多8条数据,同时把每个组最后⼀行在页中的地址,按主键从⼩到⼤的顺序记录在页⽬录中在,页⽬录中的每⼀个位置称为⼀个槽,每个槽都对应了⼀个分组,⼀旦分组中的数据行超过分组的上限8个时,就会分裂出⼀个新的分组;后续在查询某⾏时,就可以通过⼆分查找,先找到对应的槽,然后在槽内最多8个数据行中进行遍历即可,从⽽⼤幅提高了查询效率,这时⼀个页的核⼼结构就完成了
总结:分组时会在页目录中创建一个个的槽,最小行单独为一组,⼀旦分组中的数据行超过分组的上限8个时,就会分裂出⼀个新的分组,槽指向对应分组的最后一条记录,并且储存该组的主键值,方便来 ⼆分查找。
 
 

 

 
6. B+在MySQL索引中的应用 :
注意:
(1).非叶子节点存的是索引页的信息
(2).索引页保存的是主键和子节点的引用信息。
(3).叶子节点保存的是真实数据的信息
(4).叶子节点形成一个双向链表
1.以查找id为5的记录,完整的检索过程如下:
步骤一:首先找到这条记录所对页
步骤二:再找到对应的槽
步骤三:根据槽的主键值,通过二分查找找到对应的记录。
具体如下:
首先判断B+树的根节点中的索引记录,此时 5 < 7 ,应访问左孩⼦节点,找到索引页2
然后在索引页2中判断主键id的大小,找到对应的槽的主键值与之不对
最后槽的主键值,通过二分查找找到对应的记录 找到与5相等的记录,命中,加载对应的数据页。
注意:这里每进行一次查找之前都要进行一次IO加载到内存,遍历几个节点IO几次。

2.三层B+树数据存放数(略)

索引⻚⼀条数据的⼤⼩为,主键⽤BIGINT类型占8Byte,下⼀⻚地址6Byte,⼀共14Byte,⼀个 索引页可以保存 16*1024/14 = 1170 条索引记录

综合只保存索引的根节点和⼆级节点的索引⻚以及保存真实数据的数据页,那么⼀共可以保存 1170*1170*16 = 21,902,400 条记录,也就是说在两千多万条数据的表中,可以通过三次IO就完成数据的检索



四. 索引分类及使用:

注意:创建多少索引就会生成多少索引树
1.主键索引:
当在⼀个表上定义⼀个主键 PRIMARY KEY 时,InnoDB使⽤它作为聚集索引 
  
代码:创建主键两种方式:
 
方式三:修改表中的列为主键索引:(修改表中的id列为主键索引)
语法:添加:ALTER TABLE + 表名 add PRIMARY KEY (...)
修改:ALTER TABLE + 表名 modify ...

 

2. 唯⼀索引:
当在⼀个表上定义⼀个唯⼀键 UNQUE 时,自动创建唯⼀索引
与普通索引类似,但区别在于唯⼀索引的列不允许有重复值
下图是创建索引的三种方式:
 
 
 
3.普通索引:
最基本的索引类型,没有唯⼀性的限制
可能为多列创建组合索引,称为复合索引或组和索引
 
方式一:创建表的时候创建普通索引
-- 创建表的时候创建普通索引
CREATE TABLE t_index1 (
 id bigint PRIMARY KEY auto_increment,
 name varchar(20) UNIQUE,
 sno varchar(20),
 index(sno)
)

方式二:修改表中的列为普通索引

修改表中的列为普通索引
CREATE TABLE t_index2 (
 id BIGINT PRIMARY KEY auto_increment,
 name VARCHAR(20),
 sno VARCHAR(20)
 );
 
 ALTER TABLE t_index2 ADD INDEX (sno);

方式三:单独创建索引并指定索引名

 -- 单独创建索引并指定索引名 
CREATE TABLE t_index3 (
  id bigint PRIMARY KEY auto_increment,
  name varchar(20),
  sno varchar(20)
);

-- 索引名推荐使用 idx_表名_列名[_列名]
CREATE INDEX idx_t_index3 on t_index3(sno);

 

创建普通索引三种方式:

-- 创建复合索引:

-- 创建表时指定索引列
create table t_index_4 (
  id bigint PRIMARY key auto_increment,
  name varchar(20),
  sno varchar(20),
  class_id bigint,
  INDEX(sno,name)
)


-- 单独创建复合索引并指定索引名
create table t_index_6 (
  id bigint PRIMARY key auto_increment,
  name varchar(20),
  sno varchar(20),
  class_id bigint
);

CREATE INDEX idx__t_index_6_sno_name ON t_index_6 (sno,name);

 

4.全⽂索引:
4.1。基于⽂本列(CHAR、VARCHAR或TEXT列)上创建,以加快对这些列中包含的数据查询和4.2.DML操作
4.3.用于全文搜索,仅MyISAM和InnoDB引擎支持 
 
 
 
5.聚集索引:
与主键索引是同义词 如果没有为表定义 PRIMARY KEY, InnoDB使⽤第⼀个 UNIQUE 和 NOT NULL 的列作为聚集索引
注意:
如果表中没有 PRIMARY KEY 或合适的 UNIQUE 索引InnoDB会为新插⼊的行生成⼀个⾏号并用6字节的 ROW_ID 字段记录, ROW_ID 单调递增,并使⽤ ROW_ID 做为索引 
 
 
 
6 非聚集索引:
6.1.聚集索引以外的索引称为非聚集索引或⼆级索引
6.2.⼆级索引中的每条记录都包含该⾏的主键列,以及⼆级索引指定的列。
6.3.InnoDB使⽤这个主键值来搜索聚集索引中的⾏,这个过程称为回表查询 
 
7.非聚集索引的查询->回表查询解释 :
我们知道创建多少索引就会生成多少索引树.
我的理解是,通过索引查询到叶子节点的索引记录根据这个索引记录去整棵包含全部数据的索引树中查找数据的过程,因为总共查询了两张表索引叫回表查询。
例子:
-- 回表查询
select * from student where student_id = 1 and name = '韩立';

8.索引覆盖:
通过索引查询的列 不需要 根据索引记录 去整棵 包含全部数据的 索引树中查找 数据
例子:
select sn from student where name = '厉飞羽';

 

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

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

相关文章

动态内存

动态内存分配函数&#xff1a;在程序运行时为变量或数据结构开辟的内存空间的函数。 有三个重要的动态分配函数&#xff1a;malloc、calloc、realloc。 动态内存分配函数 malloc 这个函数是向内存中申请一块连续的空间&#xff0c;返回一个指向这个块空间的指针。 如果开辟成…

【Elasticsearch系列七】索引 crud

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

测试ASP.NET Core的WebApi项目调用WebService

虚拟机中部署的匿名访问的WebService&#xff0c;支持简单的加减乘除操作。本文记录在WebApi中调用该WebService的方式。   VS2022创建WebApi项目&#xff0c;然后在解决方案资源管理器的Connected Services节点点右键&#xff0c;选择管理连接的服务菜单。 点击下图圈红处…

【STM32 HAL库】IIC通信与CubeMX配置

【STM32 HAL库】IIC通信与CubeMX配置 前言理论IIC总线时序图IIC写数据IIC读数据 轮询模式CubeMX配置应用示例AHT20初始化初始化函数读取说明读取函数 中断模式CubeMX配置状态机图fsm.caht20.c DMA模式CubeMX配置代码 前言 本文为笔者学习 IIC 通信的总结&#xff0c;基于keysk…

评价类——熵权法(Entropy Weight Method, EWM),完全客观评价

目录 一、 熵权法赋权代码说明1.1 介绍 二、 手把手教你运行代码2.1 数据示例2.2 可直接运行代码2.3 shangquanfa_eg_Sheet1.csv数据可视化2.4 代码运行过程截屏2.5 代码运行结果截屏2.6 对熵权法的结果分析 三、 提供的代码如何修改&#xff1f;四、 为什么确定极小化指标&…

算法:计算二叉树的最大深度(Java实现)

思路 定义问题&#xff1a; 最大深度&#xff08;或称为最大层数&#xff09;是从根节点到最远叶子节点的路径上的节点数。我们需要找到这个最长路径的节点数。 递归的基本思路&#xff1a; 对于每个节点&#xff0c;我们需要计算其左子树的最大深度和右子树的最大深度。节点的…

54.【C语言】 字符函数和字符串函数(strncpy,strncat,strncmp函数)

和strcpy,strcat,strcmp函数对应的是strncpy,strncat,strncmp函数 8.strncpy函数 *简单使用 cplusplus的介绍 点我跳转 翻译: 函数 strncpy char * strncpy ( char * destination, const char * source, size_t num ); 从字符串中复制一些字符 复制源(source)字符串的前num个…

Redis详细解析

Redis 什么是Redis?关系型与非关系型数据库Redis可以做什么Redis入门安装在Windows系统上安装在Linux系统上安装 Redis在Linux系统上启动运行如何设置redis-server后台运行与关闭如何设置redis客户端登录时需要验证密码**设置允许远程连接redis服务**Redis数据类型Redis常用命…

魔方财务迁移指南

本文将详细介绍如何将魔方财务系统迁移到新的服务器&#xff0c;确保您能够顺利地迁移数据和系统文件。 迁移前的准备 在开始迁移之前&#xff0c;请确保新服务器满足以下配置要求&#xff1a; 操作系统&#xff1a;CentOS/Debian/Ubuntu硬件配置&#xff1a;至少2H2G&#…

RP2040 C SDK ADC功能使用

RP2040 C SDK ADC功能使用 &#x1f33f;RP2040 ADC功能说明文档&#xff1a;https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#hardware_adc &#x1f4d7;RP2040 ADC介绍 SAR ADC500 kS/s (Using an independent 48MHz clock)12 bit (RP2040 8.7 ENOB, R…

建筑资质与劳务资质的区别

在建筑行业&#xff0c;资质就像是企业的“身份证”&#xff0c;它证明了企业具备承接相应工程的能力和条件。对于刚入行的小白来说&#xff0c;可能会对建筑资质和劳务资质的区别感到困惑。别担心&#xff0c;今天我们就来聊聊这两者之间的不同。 什么是建筑资质&#xff1f; …

git push : RPC failed; HTTP 400 curl 22 The requested URL returned error: 400

git push 出现RPC failed; HTTP 400 curl 22 The requested URL returned error: 400 问题 git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (10/10), done. error: RPC …

分布式训练:(Pytorch)

分布式训练是将机器学习模型的训练过程分散到多个计算节点或设备上&#xff0c;以提高训练速度和效率&#xff0c;尤其是在处理大规模数据和模型时。分布式训练主要分为数据并行和模型并行两种主要策略&#xff1a; 1. 数据并行 (Data Parallelism) 数据并行是最常见的分布式…

数据结构之树的常用术语

二叉树的常用术语 前言 由于数组在插入、删除上的缺点和链表在查询上的缺点&#xff0c;出现了树的数据结构&#xff0c;可以在增删改查中弥补数组和链表的缺陷。 常用数据 节点&#xff1a;每个节点根节点&#xff1a;最上层的节点&#xff0c;Root节点父节点&#xff1a;相…

基于SSM的宿舍管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的宿舍管理系统拥有两种角色&#xff0c;分别为管理员和宿管&#xff0c;具体功能如下&#xff1a; 管理员&#xff1a;学生管理、班级管理、宿舍管理、卫生管理、访客管理、用户…

SOT23封装1A电流LDO具有使能功能的 1A、低 IQ、高精度、低压降稳压器系列TLV757P

前言 SOT23-5封装的外形和丝印 该LDO适合PCB空间较小的场合使用&#xff0c;多数SOT23封装的 LDO输出电流不超过0.5A。建议使用时输入串联二极管1N4001,PCB布局需要考虑散热&#xff0c;参考文末PCB布局。 1 特性 • 采用 SOT-23 (DYD) 封装&#xff0c;具有 60.3C/W RθJA •…

双指针算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 想要了解双指针算法的介绍&#xff0c;可以去看下面的博客&#xff1a;双指针算法的介绍 目录 611.有效三角形的个数 LCR 1…

【天池比赛】【零基础入门金融风控 Task2赛题理解】实战进行中……20240915更新至2.3.4.3 查看训练集测试集中特征属性只有一值的特征

2.3 代码示例 2.3.1 导入数据分析及可视化过程需要的库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import datetime import warnings warnings.filterwarnings(ignore) 2.3.2 读取文件 #读取数据时相对路径载入报错时…

【Redis】之Geo

概述 Geo就是Geolocation的简写形式&#xff0c;代表地理坐标。在Redis中&#xff0c;构造了能够存储地址坐标信息的一种数据结构&#xff0c;帮助我们根据经纬度来检索数据。 命令行操作方法 GEOADD 可以用来添加一个或者多个地理坐标。 GEODIST 返回一个key中两个成员之…

AgentTuning:提升大型语言模型的通用Agent能力

人工智能咨询培训老师叶梓 转载标明出处 大模型被用作现实中复杂任务的Agent时&#xff0c;它们的表现往往不如商业模型&#xff0c;如ChatGPT和GPT-4。这些任务要求LLMs作为中央控制器&#xff0c;负责规划、记忆和工具利用&#xff0c;这就需要精巧的提示方法和鲁棒性强的LL…