实用指南:【MySQL】索引特性

news/2025/10/5 18:02:25/文章来源:https://www.cnblogs.com/tlnshuju/p/19126804

实用指南:【MySQL】索引特性

2025-10-05 17:59  tlnshuju  阅读(0)  评论(0)    收藏  举报

一、初始索引

索引的核心工作是提高数据库性能的,MySQL的服务器,本质是在内存中的,所有数据库的CURD操作,全部都是在内存中进行的,索引也是如此。影响算法效率的因素有两个:组织数据的方式和算法本身。索引就是更改数据组织的方式,从而提高算法效率。

索引是物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行正确的
create index ,查询速度就可能提高成百上千倍。但是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的IO。所以它的价值,在于提高一个海量数据的检索速度

二、MySQL与储存

在这里插入图片描述
数据库文件,本质就是保存在磁盘的盘片中,也就是上面的一个个扇区中,数据库文件很大,因此会占据多个扇区。定位一个扇区需要知道柱面-磁头-扇区,系统读取磁盘,是以块为单位的,而不是扇区,基本单位是4KB。磁盘随机访问是本次IO给出的扇区地址和上次的扇区地址不连续,磁头需要较大移动动作才能重新开始读写,尽管相邻的两次IO操作在同一时刻发出,但如果它们的请求的扇区地址相差很大的话也只能称为随机访问,而非连续访问。

三、软件理解

MySQL作为一个应用级软件,可以想象成一种特殊的文件系统,它有着更高的IO场景,为了提高IO效率,MySQL进行IO的基本单位是16KB,这个基本数据单元,在MySQL里叫做page

MySQL 将数据以页(page)为单位存储在磁盘中。在执行增删改查(CURD)操作时,系统需要通过计算来定位数据插入位置,或查找待修改、查询的具体数据。

而只要涉及计算,就需要CPU参与,而为了便于CPU参与,一定要能够先将数据移动到内存当中。所以在特定时间内,数据一定是磁盘中有,内存中也有。后续操作完内存数据之后,以特定的刷新策略,刷新到磁盘。而这时,就涉及到磁盘和内存的数据交互,也就是IO了。而此时IO的基本单位就是Page。

为了更好的进行上面的操作, MySQL 服务器在内存中运行的时候,在服务器内部,就申请了被称为 Buffer Pool 的的大内存空间,来进行各种缓存。其实就是很大的内存空间,来和磁盘数据进行IO交互。总之就是一句话:为了更高的效率,一定要尽可能的减少系统和磁盘IO的次数在这里插入图片描述

四、Page

当我们向一个具有主键的表中乱序插入数据后,我们会发现数据会自动排序。理解这个现象前,我们先重谈一下page。在MySQL内部一定会同时存在大量的page,因此MySQL会对其进行管理,这样一来page就不仅仅是一个大一点的内存块了,page内部也必须写入对应的管理信息struct page,就像:

struct page
{
struct page* next;
struct page* prev;
char buffer[NUM]
;
}
;
//---16KB

申请page其实就是new page(),将所有page用“链表”(或其他结构)管理起来,这就是在buffer pool内部,对MySQL中的page进行了一个建模。

MySQL 采用 Page 方案进行磁盘 IO 交互,主要基于以下考虑:

假设需要查找 id=2 的记录,如果采用逐条加载的方式,第一次加载 id=1,第二次加载 id=2,需要 2 次 IO。若查找id=5,则需要 5 次 IO。这种逐条加载的方式会导致 IO 次数显著增加。

而采用 Page 方案时,假设这 5 条记录(或更多)都存储在一个 16KB 的 Page 中,查找 id=2 时,整个 Page会被一次性加载到 MySQL 的 Buffer Pool 中,仅需 1 次 IO。后续查找 id=1、3、4、5等记录时,可以直接在内存中完成,无需额外 IO。这种方式显著减少了 IO 次数。

你可能会问:如何确保用户下次查找的数据就在这个 Page 中?虽然无法严格保证,但根据局部性原理,这种可能性很大。程序在执行时往往具有空间局部性和时间局部性,即相邻的数据很可能被连续访问。 此外,IO 效率低下的主要瓶颈通常不是单次 IO 的数据量大小,而是 IO 的次数。通过 Page 方案,可以有效减少 IO次数,从而提升整体性能。

因为有主键,MySQL 会默认按照主键给我们的数据进行排序,从Page内数据记录可以看出,数据是有序且彼此关联的,但是如果page间按照下图的链表结构,查找特定的一条记录就是线性遍历,这样的话效率就太低了:
在这里插入图片描述
此时就要引入页目录这一概念了,一本书拥有目录,便于在一本书中进行快速查找。针对上述的单页Page,我们也可以引入目录:
在这里插入图片描述
从这里我们就明白为什么MySQL会通过键值来自动排序了,就是为了更方便地引入目录

但这里只是解决了Page内部查询的问题,而Page之间仍然是线性的,若Page很多的情况下效率仍然是存在问题的,按照之前解决问题的思路,我们可以也给Page带上目录。
在这里插入图片描述
在这里插入图片描述
当然我们还能给页目录再向上加一个页目录,如下图所示,这个结构其实就是B+树。叶子节点保存数据,而非叶子节点不存数据,因此可以存储更多的目录项,这样就能管理更多的page,宏观上看这颗树就是一个矮胖型的树,这样的形状意味着从顶到底路径上的节点是很少的,找到目标数据只需要更少的Page,从而IO次数也减少,提高了效率。

同时叶子节点是用链表级联起来的,这是B+树的特点,这么设计的原因就是为了进行范围查找,这样就不用每次查找都从顶开始。
在这里插入图片描述这整个结构叫做MySQL InnoDB下的索引结构,我们已经完成了主键索引。一般我们建表插入数据的时候,就是在该结构下进行增删查改,就算我们的表没有主键,MySQL也会自动生成一个隐藏列来充当主键。

其他数据结构为什么不适合?

1.链表:线性遍历,效率低
2.二叉搜索树:“瘦高状”,从顶到底遇到的节点(IO次数)较多,而且极端情况下会退化为线性结构
3.AVL&红黑树:虽然是近似平衡,但形状仍然不变,层数是比B+树高的,B+树更加适合
4.Hash:?官方的索引实现方式中, MySQL 是支持HASH的,不过 InnoDB 和 MyISAM 并不支持,Hash跟进其算法特征,决定了虽然有时候也很快(O(1)),不过,在面对范围查找就明显不行
5.B树:B树的非叶子节点存了数据,意味着整体形状更高瘦,IO效率较低,并且非叶子节点是没有级联的,范围查找也不方便

五、聚簇/非聚簇索引

MyISAM存储引擎同样也是使用B+树作为搜索结果,但叶节点存放的是数据的地址,这就是MyISAM的最大特点,索引Page和数据Page分离,即叶节点也没有数据,只有数据对应的地址,这种用户数据和索引分离的索引方案叫做非聚簇索引
在这里插入图片描述
而InnoDB这种用户数据和索引数据放在一起的的索引方案叫做聚簇索引,当然MySQL除了默认会建立主键索引外,我们用户有可能建立其他列信息建立的索引,一般这种索引可以叫做辅助索引,对于MyISAM而言辅助索引和主键索引没有区别,无非是主键不能重复而非主键可以重复而已。而对于InnoDB而言,非主键索引的叶子节点中并没有数据,只有对应记录的Key值,所以通过辅助索引,找到目标记录,需要两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。这种过程,就叫做回表查询,为什么不给辅助索引的叶子节点也给上数据呢?原因就是太浪费空间了。
在这里插入图片描述

六、索引操作

索引创建规则

1.比较频繁作为查询条件的字段应该创建索引
2.唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件,如性别
3.更新非常频繁的字段不适合创建索引
4.不会出现在where子句中的字段不该创建索引

1.创建主键索引

#方法一
create
table user1(id int
primary
key
,name varchar(30
)
)
;
#方法二
create
table user2(id int
,name varchar(30
)
,
primary
key(id)
)
;
#方法三
create
table user3(id int
,name varchar(30
)
)
;
alter
table user3 add
primary
key(id)
;

主键索引的特点:

1.一个表中最多只有一个主键索引
2.主键索引效率高,因为主键不可重复

2.创建唯一索引

#方法一
create
table user4(id int
primary
key
,name varchar(30
)
unique
)
;
#方法二
create
table user5(id int
primary
key
,name varchar(30
)
,
unique(name)
)
;
#方法三
create
table user6(id int
primary
key
, name varchar(30
));
alter
table user6 add
unique(name)
;

唯一索引的特点:

1.一个表中可以有多个唯一索引
2.查询效率高

3.创建普通索引

#方法一
create
table user8(id int
primary
key
,
name varchar(20
)
,
email varchar(30
)
,
index(name) --在表的定义最后,指定某列为索引
)
;
#方法二
create
table user9(id int
primary
key
, name varchar(20
)
, email varchar(30
)
)
;
alter
table user9 add
index(name)
;
--创建完表以后指定某列为普通索引
#方法三
create
table user10(id int
primary
key
, name varchar(20
)
, email varchar(30
)
)
;
-- 创建一个索引名为 idx_name 的索引
create
index idx_name on user10(name)
;

普通索引的特点:

1.一个表中可以有多个普通索引,在实际开发中用的比较多
2.如果某些列需要创建索引,同时该列有重复的值,那么就该使用普通索引

4.查询索引

在这里插入图片描述

5.删除索引

在这里插入图片描述

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

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

相关文章

镇江做网站公司漳州本地企业网站建设服务

作者推荐 【动态规划】【广度优先搜索】【状态压缩】847 访问所有节点的最短路径 本文涉及知识点 动态规划汇总 LeetCode879. 盈利计划 集团里有 n 名员工,他们可以完成各种各样的工作创造利润。 第 i 种工作会产生 profit[i] 的利润,它要求 group[…

用 Haxe 实现英文数字验证码识别

一、背景介绍 验证码(CAPTCHA)广泛用于区分人类与机器人,识别验证码通常依赖图像处理与 OCR 技术。本文将使用 Haxe 编程语言结合 Tesseract OCR 来实现英文数字验证码的识别。 Haxe 是一门跨平台语言,可以编译到多…

出题四

T1 T4tjT1 对于一次询问 \((x_1,y_1)\) 到 \((x_2,y_2)\),显然若两点不在同一个联通块中则无解。考虑在同一个联通块中的答案。 我们对整张图进行黑白染色。则有结论:若黑色/白色格点存在不同的数,则一定有解。 证明…

网站推广由什么样的人来做网站后台上次图片

本文作者:dpgisdpg前言参加一起Show桌面活动,顺便搞定之前未做的三星C49HG90DMC显示器开箱作业。搭建一套美如画的桌面,工程堪比“复仇者联盟”,不但需要足够的财力来买装备,还得会构图和互相搭配,打个比方…

网站设计公司深圳缩我短网址生成

1.开发背景 基于以上的章节,了解了 FreeRTOS 多线程间的信号量、队列的使用,已经满足了日常使用场景。其中,队列的使用规定了队伍成员的大小,然而现实使用场景下,很多数据不都是定长大小了,例如不定长的通讯…

二手图书交易网站建设辽宁移动惠生活app官方版

一、新建一个项目 首先,下载微信小程序开发工具,具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后,注册小程序账号,具体注册方法,可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

ios移动网站开发详解高端室内设计公司

活动介绍: 「数据仓库技术交流群」已经正式启动每日SQL打卡,帮助大家扎实基础,努力工作之余,别忘了自我提升。 欢迎报名和邀请小伙伴参与,一个人可能走得很快,但一群人会走得很远。 🍅题目汇总(…

实用指南:B站视频下载器 v1.0.4|免登录下载1080P视频

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

台州椒江做网站wordpress禁止搜索页面

队列定义 先进者先出,这就是典型的“队列”。队列跟栈一样,也是一种操作受限的线性表数据结构。 顺序队列和链式队列 顺序队列:用数组实现的队列// 用数组实现的队列 public class ArrayQueue {// 数组:items,数组大…

7 2025 07 15 模拟赛题解

2025 07 15 模拟赛题解 T1 水题一道,全场切 题面 请你判断是否存在正整数 \(n\),使得 \(n^2\) 是 k 的倍数,且 \(n\) 不是 \(k\) 的倍数。如果存在,则输出最小的 \(n\)。不存在则输出 \(−1\)。 \(1 \le k \le 10 …

路桥区商用营销型网站建设wordpress如何查看并修改源代码

SpringCloud Alibaba 常用组件 一、基础结构搭建1.父工程创建2.子工程创建 二、Nacos:注册中心1.服务端搭建2.注册中心-客户端搭建3.注册中心-管理页面4.注册中心-常用配置5.注册中心-核心功能总结 三、Nacos注册中心集成Load Balancer 、OpenFeign1.Nacos客户端集成…

使用 OCaml 实现验证码识别

一、背景介绍 验证码(CAPTCHA)是一种常见的人机验证方式,通常由随机生成的字母或数字组成。为了自动化识别验证码,我们可以结合 OCR 引擎 Tesseract 与编程语言进行处理。本文使用 OCaml 实现验证码识别。 二、技术…

资料中台(大材料平台)之数据仓库建设

资料中台(大材料平台)之数据仓库建设pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

私有云大数据部署:从开发到生产(Docker、K8s、HDFS/Flink on K8s) - 详解

私有云大数据部署:从开发到生产(Docker、K8s、HDFS/Flink on K8s) - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fami…

建设网站注意什么wordpress表单数据前台显示图片

近年来,我国各类器材制造业已经开始向数字化生产转型,使得生产流程变得更加精准高效。通过应用智能设备、物联网和大数据分析等技术,企业可以更好地监控生产线上的运行和质量情况,及时发现和解决问题,从而提高生产效率…

本地搭建多个网站wordpress文章阅读量

检索销量表中销量最好的商品id和销量,下列SQL语句正确的是() A. SELECT 商品id,销量 FROM 销量表 WHERE 销量MAX(销量) B. SELECT 商品id,MAX(销量) FROM 销量表 GROUP BY 销量 C. SELECT 商品id,MAX(销量) FROM 销量表 GROUP BY 商品id …

3g版网站制作wordpress分城市访问

临界区模式 Critical Section Pattern 是指在一个共享范围中只让一个线程执行的模式.它是所有其它多线程设计模式的基础,所以我首先来介绍它.把着眼点放在范围上,这个模式叫临界区模式,如果把作眼点放在执行的线程上,这个模式就叫单线程执行模式.首先我们来玩一个钻山洞的游戏,…

差分约束模板

洛谷模板测试七倍经验: https://www.luogu.com.cn/record/238785118 https://www.luogu.com.cn/record/238783283 https://www.luogu.com.cn/record/238788990 https://www.luogu.com.cn/record/238791631 https://ww…

第一篇:揭示模型上下文协议(MCP):AI的通用连接器 - 详解

第一篇:揭示模型上下文协议(MCP):AI的通用连接器 - 详解2025-10-05 17:35 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !importa…

17 LCA模拟赛1T2 剧院始于演员 题解

剧院始于演员 题面 有 \(n\) 个演员,共 \(m\) 场演出,每场演出会给出这场演出的演员名单,共 \(k_i\) 个姓名 对于每个演员,求最早在哪一场演出结束后能够确定其对应姓名? \(1 \le n , m \le 10^5, \sum k_i \le 1…