(MySQL)索引

news2024/12/23 12:58:24

注:此博文为本人学习过程中的笔记

1.简介

1.1.概念 

MySQL的索引是一种数据结构,它可以帮助数据库高效地查询,更新数据表中的数据。索引通过一定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快查询

MySQL索引类似于书籍的目录,通过指向数据行的位置,可以快速定位和访问表中的数据,比如汉语字典的目录页,我们可以按笔画,偏旁部首, 拼音等排序的目录(索引)快速查找到需要的字

1.2.为什么要使用索引 

显而易见,使用索引的目的只有一个,就是提升数据检索的效率,在应用程序的运行过程中,查询操作的频率远远高于增删改的频率 

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

2.1.HASH 

时间复杂度是O(1),查询速度非常快,但是MySQL并没有选择HASH作为索引的默认数据结构,主要原因是HASH不支持范围查找

2.2.二叉搜索树 

二叉树搜索树的中序遍历是一个有序数组,但有几个问题导致它不适合用作索引的数据结构

1.最坏情况下二叉搜索树会形成一个单边树,时间复杂度为O(N)

2.节点个数过多无法保证树高

AVL和红黑树,虽然是平衡或者近似平衡,但是毕竟是二叉结构

在检索数据时,每次访问某个节点的子节点时都会发生一次磁盘IO,而在整个数据库系统中,IO是性能的瓶颈,减少IO次数可以有效的提升性能

2.3.N叉树 

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

2.4.B+树 

2.4.1.简介 

B+树是一种经常用于数据库和文件系统等场合的平衡查找树,是MySQL索引采用的数据结构 

2.4.2.B+树的特点 

能够保持数据稳定有序,插入与修改有较稳定的时间复杂度

非叶子节点仅具有索引作用,不存储数据,所有叶子节点保存真实数据

所有叶子节点构成一个有序链表,可以按照key排序的次序一次遍历全部数据

2.4.3.B+树与B树的对比

叶子节点中的数据是连续的,且相互链接,便于区间查找和搜索

非叶子节点的值都包含在叶子节点中

对于B+树而言,在相同树高的情况下,查找任一元素的时间复杂度都一样,性能均衡 

3.MySQL中的页 

3.1.为什么要使用页 

在.ibd文件(MySQL使用的是innodb存储引擎)中最重要的结构体就是Page(页),页是内存与磁盘交互的最小单元,默认大小为16kb,每次内存与磁盘的交互至少读取一页,所以在磁盘中每个页内部的地址都是连续的,之所以这样做,是因为在使用数据的过程中,根据局部性原理,将来要使用的数据大概率与当前访问的数据在空间上是临近的,所以一次从磁盘读取一页的数据放入内存中,当下次查询的数据还在这个页中时就可以从内存中直接读取,从而减少磁盘IO提高性能

局部性原理:

是指程序在执行时呈现出局部性规律,在一段时间内,整个程序的执行仅限于程序中的某一部分。相应地,执行所访问的存储空间也局限于某个内存区域,局部性通常有两种形式:时间局部性和空间局部性

时间局部性:如果一个信息项正在被访问,那么在近期它很可能会被再次fangwen

空间局部性:将来要用到的信息大概率与正在使用的信息在空间地址上是临近的

每一个页中即使没有数据也会使用16kb的存储空间,同时与索引的B+树中的节点对应,可以通过系统变量innodb_page_size查看

在MySQL中有多种不同类型的页,最常用的就是用来存储数据和索引的“索引页”,也叫做“数据页”,但不论哪种类型的页都会包含页头和页尾,页的主体信息使用“数据行”进行填充

3.2.页文件头和页文件尾

页头和页尾包含了很多信息,我们只需要知道在页头中包含了上一页页号和下一页页号,通过这两个属性可以把页与页之间连接起来,形成一个双向链表

3.3.页主体 

页主体部分就是存储真实数据的主要区域,每当创建一个新页,都会自动分配两个行,一个是页内最小行Infimun,另一个是页内最大行Supremun,这两个行并不存储任何真实信息,而是作为数据行链表的头和尾,第一个数据行有一个记录下一行的地址偏移量的区域next_record将页内的数据行组成了一个单向链表

当向一个新页插入数据时,将Infimun连接第一个数据行,最后一行真实数据行连接Supremun,这样数据就构建成了一个单向链表,更多的行数据插入后,会按照主键从小到大的顺序进行连接 

3.4.页目录

当按主键或索引查找某条数据时,最直接简单的方式就是从头行Infimun开始,沿着链表顺序逐个比对查找,但一个页有16kb,通常会存在数百行数据,每次都要遍历数百行,无法满足高效查询,为了提高查询效率, innodb采用二分查找来解决查询效率问题;

具体实现方式是,在每一个页中加入一个叫做页目录page directory的结构,将页内包括头行,尾行在内的所有行进行分组,约定头行单独为一组,其他每个组最多8行数据,(尾行存在最后一组)同时把每个组最后一行在页中的地址,按主键从小到大的顺序记录在页目录中,页目录中的每一个位置称为一个槽,每个槽都对应了一个分组,一旦分组中的数据超过分组的上限8个时,就会分裂出一个新的分组;

后续在查询某行时,就可以通过二分查找,先找到对应的槽,然后在槽内最多8个数据行中进行遍历即可,从而大幅提高了查询效率,这时一个页中的核心结构就完成了

4.B+树在索引中的应用 

根据索引的不同会生成不同的树,有普通索引树和主键索引树等,非叶子节点保存索引数据,叶子节点保存真实数据 

4.1.计算三层树高的B+树可以存放多少条记录 

假设一条用户数据大小为1kb,在忽略数据页中数据页自身属性空间占用的情况下,一页可以存16条数据

索引页一条数据的大小为,主键用bigint类型占8byte,下一页地址占6byte,一共是14byte,一个索引页可以保存16*1024/14 = 1170条索引记录 

如果只有三层树高的情况,综合只保存索引的根节点和二级节点的索引页以及保存真实数据的数据行,那么一共可以保存1170*1170*16 = 21902400条记录,也就是说在两千多万条数据的表中,可以通过三次IO就完成数据的检索

5.索引分类

5.1.主键索引

当在一个表上定义一个主键primary key时,innodb使用它作为聚集索引

推荐为每个表定义一个主键。如果没有定义主键以及表中没有逻辑上唯一且非空的列可以使用主键,那MySQL会自己添加一个看不见的自增列,列名为row_id,来产生索引的作用 

5.2.普通索引 

最基本的索引类型,没有唯一性的限制

可能为多列创建组合索引,称为复合索引或组全索引

5.3.唯一索引 

当在一个表中定义一个唯一键unique时,自动创建唯一索引。

与普通索引类似,但区别在于唯一索引的列不允许有重复值

5.4.全文索引

基于文本列(char,varchar或text列)上创建,以加快对这些列中包含的数据查询和dml操作

用于全文搜索,仅MyISAM和innodb引擎支持

注意MySQL并不擅长存储文本,因此当需要存储文本时会选择其他数据库 

6.使用索引

6.1.自动创建 

当我们为一张表加主键约束(primary key),外键约束(foreign key),唯一键约束(unique)时,MySQL会为对应的列自动创建一个索引

如果表不指定任何约束时,MySQL会自动为每一列生成一个索引并用row_id进行标识

6.2.手动创建

6.2.1.主键索引

-- 方式一,创建表时创建主键
create table t_test_pk(
    id bigint primary key auto_increment,
    name varchar(20)
);

-- 方式二,创建表时单独指定主键列
create table t_test_pk1(
    id bigint auto_increment,
    name varchar(20),
    primary key(id)
);

-- 方式三,修改表中的列为主键索引
create table t_test_pk2(
    id bigint,
    name varchar(20)
);

alter table t_test add primary key(id);
alter table t_test_pk2 modify id bigint auto_increment;

6.2.2.唯一索引

-- 方式一,创建表时创建唯一键
create table t_test_uk(
    id bigint primary key auto_increment,
    name varchar(20) unique
);

-- 方式二,创建表时单独指定唯一列
create table t_test_uk1(
    id bigint primary key auto_increment,
    name varchar(20),
    unique(name)
);

-- 方式三,修改表中的列为唯一索引
create table t_test_uk2(
    id bigint primary key auto_increment,
    name varchar(20)
);

alter table t_test_uk2 add unique(name);

6.2.3.普通索引

-- 方式一,创建表时指定索引列
create table t_test_index(
    id bigint primary key auto_increment,
    name varchar(20) unique,
    sno varchar(10),
    index(sno)
);

-- 方式二,修改表中的列为普通索引
create table t_test_index1(
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10)
);
alter table t_test_index1 add index(sno);

-- 方式三,单独创建索引并指定索引名
create table t_test_index2(
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10)
);
create index index_name on t_test_index2(sno);

6.3.创建复合索引 

创建语法与创建普通索引相同,只不过指定多个列,列与列之间用逗号隔开

-- 方式一,创建表时指定索引列
create table t_test_index4(
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10),
    class_id bigint,
    index(sno, class_id)
);

-- 方式二,修改表中的列为复合索引
create table t_test_index5(
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10),
    class_id bigint
);
alter table t_test_index5 add index(sno, class_id);

-- 方式三,单独创建索引并指定索引名
create table t_test_index6(
    id bigint primary key auto_increment,
    name varchar(20),
    sno varchar(10),
    class_id bigint
);
create index index_name on t_test_index6(sno, class_id);

6.4.查看索引 

-- 方式一
show keys from t_test_index6;

-- 方式二
show index from t_test_index6;

-- 方式三,简要信息
desc t_test_index6;

6.5.删除索引 

6.5.1.主键索引 

-- 语法
alter table 表明 drop primary key;

-- 示例,删除t_test_index6表中的主键
alter table t_test_index6 drop primary key;

-- 如果提示由于自增列产生错误,先删除自增属性再删除主键
alter table t_test_index6 modify id bigint;
alter table t_test_index6 drop primary key;

6.5.2.其他索引

-- 语法
alter table 表名 drop index 索引名;

-- 示例,删除t_test_index6表中名为index_name的索引
alter table t_test_index6 drop index index_name;

6.6.创建索引的注意事项 

索引应该创建再高频查询的列上

索引需要占用额外的存储空间

对表进行插入,更新,删除操作时,同时也会修改索引,可能会影响性能

创建过多或不合理的索引会导致性能下降,需要谨慎选择和规划索引

7.查看SQL语句是否使用索引

我们可以使用explain(查看执行计划) 

其中type表示访问类型,有以下几种分类,性能由差到好

1.ALL:扫描全表

2.index:扫描全部索引树 

3.range:扫描部分索引,索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行,常见于between,<,>等的查询

4.ref:使用非唯一索引或唯一索引的前缀进行的查找,不是主键或不是唯一索引

5.eq_ref:唯一性索引扫描,对于每个索引键,表中只有一个记录与之匹配,常见于主键索引或唯一索引扫描

6.const,system:单表中最多有一个匹配行,查询起来非常迅速,例如根据主键或唯一索引查询,system是const类型的特例,当查询的表只有一行的情况下,使用system

7.null:不用访问表或者索引,直接就能得到结果

8.索引覆盖和回表查询 

回表查询是指通过索引树中的值,去对应的数据树获得相应的信息

索引覆盖是指通过查询索引树直接查询到需要的需要的数据,不需要回表查询了

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

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

相关文章

NOIP2023(惨烈)做题记(泪奔::>_<::)

P9868 [NOIP2023] 词典 1.这道题倒是做出来了&#xff0c;大概思路如下&#xff1a; 对于每一个字符串&#xff0c;可以存储一个 k 和 k2​ 分别表示这个字符串包含的字符中的字典序最小字符与字典序最大字符&#xff0c;这一步可以初始就处理好。 然后判断每一个字符串是否…

Windows模拟电脑假死之键盘鼠标无响应

Windows模拟电脑假死之键盘鼠标无响应 1. 场景需求 模拟Windows电脑假死&#xff0c;失去键盘鼠标响应。 2. 解决方案 采用Windows系统提供的钩子(Hook) API 拦截系统鼠标键盘消息。 3. 示例程序 【1】. 创建MFC对话框项目 新建一个MFC应用程序项目&#xff0c;项目名称…

3.3 Thymeleaf语法

文章目录 引言Thymeleaf标签显示标签链接地址标签条件判断标签元素遍历标签 Thymeleaf表达式变量表达式选择变量表达式消息表达式链接表达式 Thymeleaf内置对象上下文对象上下文变量上下文区域请求对象响应对象会话对象日期对象 实战演练创建控制器创建模板页面 结语 引言 Thy…

Spring AI Java程序员的AI之Spring AI(一)

SpringAI 基础使用 前言Spring AIChatClientImageClientOpenAiAudioTranscriptionClientEmbeddingClient 总结 前言 Spring AI&#xff0c;听着名字就感觉很好使用&#xff0c;快速上手&#xff0c;虽然功能没有太完善&#xff0c;但是社区活跃度很高&#xff0c;可以看看源码…

【LVGL快速入门(二)】LVGL开源框架入门教程之框架使用(UI界面设计)

零.前置篇章 本篇前置文章为【LVGL快速入门(一)】LVGL开源框架入门教程之框架移植 一.UI设计 介绍使用之前&#xff0c;我们要学习一款LVGL官方的UI设计工具SquareLine Studio&#xff0c;使用图形化设计方式设计出我们想要的界面&#xff0c;然后生成对应源文件导入工程使用…

C++初阶学习第七弹——string的模拟实现

C初阶学习第六弹------标准库中的string类_c语言返回string-CSDN博客 通过上篇我们已经学习到了string类的基本使用&#xff0c;这里我们就试着模拟实现一些&#xff0c;我们主要实现一些常用到的函数。 目录 一、string类的构造 二、string类的拷贝构造 三、string类的析构函…

基于SpringBoot的智能餐厅点餐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

每日一练:不同的二叉搜索树

96. 不同的二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 题目要求&#xff1a; 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a…

PAT甲级-1003 Emergency

题目 题目大意 给出n个城市的连通图&#xff0c;其中共有m条边&#xff0c;起点为C1&#xff0c;终点为C2。每个城市都有一定数目的救援队&#xff0c;现从C1出发&#xff0c;每经过一个城市&#xff0c;都可以加上这个城市的救援队。要求从C1到C2最短路径的个数&#xff0c;并…

AIGC技术的学习 系列一

文章目录 前言一、AIGC技术演进1.1 图像视频生成1.2. 文本生成1.3. 多模态生成1.4. 小结二、CAD&CAE软件介绍2.1. CAD软件2.2. CAE软件2.3. 小结三、AIGC技术与CAD&CAE软件的集成案例3.1. 土建设计领域3.2. 机械设计领域四、结语五、参考文献总结前言 在全球智能制造的…

FreeRTOS - 信号量

在学习FreeRTOS过程中&#xff0c;结合韦东山-FreeRTOS手册和视频、野火-FreeRTOS内核实现与应用开发、及网上查找的其他资源&#xff0c;整理了该篇文章。如有内容理解不正确之处&#xff0c;欢迎大家指出&#xff0c;共同进步。 队列用于传输数据&#xff1a;在任务之间、任务…

冻干咖啡市场洞察:销售额占比背后的消费密码

冻干咖啡销售额前十占比分析 一、概述 本报告基于从淘宝商品搜索接口和淘宝精确月销量接口中提取的数据&#xff0c;分析了前十个品牌在销售额上的占比情况。分析涵盖了销售额和占比的数据&#xff0c;为决策提供了依据。&#xff08;数据获取时间&#xff1a;2024.09.20&…

音乐播放器项目专栏介绍​

1.简介 本专栏使用Qt QWidget作为显示界面&#xff0c;你将会学习到以下内容&#xff1a; 1.大量ui美化的实例。 2.各种复杂ui布局。 3.常见显示效果实现。 4.大量QSS实例。 5.Qt音频播放&#xff0c;音乐歌词文件加载&#xff0c;展示。 6.播放器界面换肤。 相信学习了本专栏…

C++【内存管理】(超详细讲解C++内存管理以及new与delete的使用和原理)

文章目录 1.C/C内存分布2.C语言中动态内存管理方式3.C内存管理方式3.1 new/delete操作内置类型3. 2new/delete操作自定义类型 4. operator new与operator delete函数&#xff08;重点&#xff09;5. new和delete的实现原理5.1 内置类型5.2 自定义类型5.2.1 自定义类型调用new[]…

【机器学习】特征降维|低方差过滤|主成分分析PCA|相关系数法|皮尔逊相关系数|斯皮尔曼相关系数

特征降维 特征降维 为什么要进行特征降维? 特征对训练模型非常重要,当用于训练的数据集包涵一些不重要的特征时,可能会导致模型泛化性能不加 eg&#xff1a;某些特征的取值较为接近&#xff0c;其包含的信息较少eg&#xff1a;希望特征独立存在对预测产生影响&#xff0c;两…

Unity使用TriangleNet参考

TriangleNet下载如下&#xff1a; TriangleNet 效果如下&#xff1a; 代码参考如下&#xff1a; using System.Collections.Generic; using UnityEngine; using TriangleNet.Geometry;public class TestTriangleNet : MonoBehaviour {[SerializeField]Material material;voi…

2024下半年,国内大模型六小虎最新发展情况怎么样了?

最近大模型圈有点冷,ChatGPT访问量下降,英伟达的股价都跟着跌,更是有人开始唱衰大模型。这感觉就像经历了一场盛夏酷暑后的骤然降温,资本市场也开始理性回归。但与此同时,国内的"六小虎"却展现出另一番景象——热火朝天!这真是冰火两重天啊! 在这看似矛盾的局…

CNStream流处理多路并发Pipeline框架相关问题整理:Pipeline整体流程、数据传输、多路并发

目录 1 CNStream之前博客汇总 1.1 Pipeline中的EventBus 1.2 Pipeline中的内存池 1.3 Pipeline中的视频解码流程分析 1.4 Pipeline中的视频编码流程分析 1.5 Pipeline中的反射机制 1.6 Pipeline中的单例模式代码 1.7 怎么将CNStream适配到NVIDIA Jetson Orin 2 构建Pi…

EI收录检索报告是什么样的?怎么出具?一文了解!

一、EI检索报告是什么 EI(Engineering Village)数据库是全球最全面的工程检索二次文献数据库&#xff0c;它收录了7,000,000多篇论文的参考文献和摘要。这些论文出自5,000多种工程类期刊、会议论文集和技术报告。EI收录的文献涵盖了所有的工程领域&#xff0c;其中大约22%为会…

聊聊零基础如何开始学习鸿蒙开发技术

鸿蒙系统是一款分布式操作系统&#xff0c;其适用范围非常广泛&#xff0c;从智能手机到家用电器&#xff0c;再到工业设备&#xff0c;都能找到应用场景。特别是在智能家居领域&#xff0c;鸿蒙系统可以实现不同设备之间的无缝连接和协同工作&#xff0c;提供更加智能和便利的…