MySQL系列


文章目录

  • MySQL系列
  • 前言
  • 案例
  • 一、认识MySQL与磁盘
    • 1.1 MySQL与存储
    • 1.2 MySQL 与磁盘交互基本单位
  • 二、 MySQL 数据交互核心:BufferPool 与 IO 优化机制
  • 三、索引的理解
    • 3.1 测试案例
    • 3.2 page
    • 3.3 页目录
    • 3.3 对比其他结构
  • 四、聚簇索引 VS 非聚簇索引
  • 五、索引操作
    • 5.1 创建主键索引
    • 5.2 唯一索引的创建
    • 5.3 普通索引的创建
    • 5.4 查询索引
    • 5.5 删除索引


前言

上一篇:MySQL 函数大赏:聚合、日期、字符串等函数剖析

在MySQL数据库中,索引是一种特殊的数据结构,它与表中数据关联,就像书籍的目录与正文的关系——目录通过章节标题和页码快速定位内容,而索引则通过存储数据的关键列值及其对应物理位置,帮助数据库快速定位目标数据。


本篇文章以主流的InnoDB引擎为例,展开介绍

案例

在MySQL中操作存储大量数据的表时,我们往往会面临处理数据慢,性能低下等问题,这时只需要建立索引就可以将这种问题优化。

在这里插入图片描述

在这里插入图片描述
从操作执行时间不难看出,建立索引给我们操作带来的巨大提升。

在学习索引是如何优化MySQL的性能之前,需要先知道MySQL为什么存在性能方面的问题。

一、认识MySQL与磁盘

1.1 MySQL与存储

MySQL 给用户提供数据存储服务的,早在之前我就介绍过,MySQL使用的库、表对数据存储,在Linux下都表现为特殊结构的文件,要想对数据进行持久化保存,这些文件最终都要存储在磁盘中,所有MySQL下数据存储在磁盘这个外设当中,相比于计算机其他电子元件,磁盘效率是比较低的,在加上IO本身的特征,可以知道,如何提交效率,是 MySQL 的一个重要话题。

Linux文件系统
这篇文章中详细介绍了系统对磁盘的访问,强烈建议看一下,这里就不介绍了

1.2 MySQL 与磁盘交互基本单位

MySQL 作为一款应用软件,可以想象成一种特殊的文件系统,它有着更多的IO需求,而IO操作会大大影响执行效率,所以,为了提高基本的IO效率, MySQL 进行IO的基本单位是 16KB

磁盘这个硬件设备的基本单位是 512 字节,操作系统在和磁盘交互时以4KB为单位,而 MySQL InnoDB引擎使用 16KB 和内存进行IO交互。所以可以理解为, MySQL 和磁盘进行数据交互的基本单位是 16KB 。这个基本数据单元,在 MySQL 这里叫做page(注意和系统的page区分)。

 SHOW GLOBAL STATUS LIKE 'innodb_page_size';

在这里插入图片描述
使用这个sql语句可以查找引擎页大小

二、 MySQL 数据交互核心:BufferPool 与 IO 优化机制

通过前文介绍可知,MySQL 中的数据文件在磁盘上以 page(16KB) 为单位存储。当执行 CURD(增删改查)操作时,MySQL 需先通过计算定位目标数据的位置——这一过程依赖 CPU 参与,而 CPU 只能直接操作内存数据。因此,数据必须先从磁盘临时加载到内存中,形成“磁盘一份、内存一份”的临时状态。待内存中的数据操作完成后,再通过特定策略将更新同步回磁盘,这一过程即涉及磁盘与内存的交互(IO),而 IO 的基本单位正是 page

为高效管理内存中的数据、减少频繁的磁盘 IO,MySQL 服务器在启动时会在内存中申请一块专用的大内存区域,称为 BufferPool(缓冲池)。它的核心作用是:

  • 缓存热点数据:将频繁访问的 page 临时存储在内存中,避免每次操作都直接读写磁盘(局部性原理:当你对某一块数据操作时,你的下一次操将有很大概率,会使用后面的数据)。
  • 优化 IO 效率:所有数据操作先在 BufferPool 中完成,操作完成后同步到磁盘,大幅减少磁盘 IO 次数(不可以操作一行,就获取一行)。

因此,减少系统与磁盘的 IO 次数是提升 MySQL 效率的核心原则,而 BufferPool 正是实现这一目标的关键机制——它通过内存缓存降低了磁盘 IO 对性能的影响。

三、索引的理解

3.1 测试案例

建立测试表
create table if not exists user (
id int primary key, --一定要添加主键哦,只有这样才会默认生成主键索引
age int not null,
name varchar(16) not null
);
插入多条记录,注意此处数据的主键顺序
insert into user (id, age, name) values(3, 18, '杨过');insert into user (id, age, name) values(4, 16, '小龙女');insert into user (id, age, name) values(2, 26, '黄蓉');insert into user (id, age, name) values(5, 36, '郭靖');insert into user (id, age, name) values(1, 56, '欧阳锋');

在这里插入图片描述
可以发现MySQL会将插入的数据默认变为有序,那么这样做有什么好处呢?
排序插入是为了优化查询效率

具体形式后面介绍

3.2 page

我们目前可以简单理解一个独立表文件是由一个或者多个Page构成的,那么这个表该如何管理这些page呢?
在这里插入图片描述
不同的 Page ,在 MySQL 中,都是 16KB ,使用 prevnext 构成双向链表(像这种结构在学习Linux时,我们经常遇到),因为有主键的问题, MySQL 会默认按照主键给我们的数据进行排序,从上面的Page内数据记录可以看出,数据是有序且彼此关联的。

页内部存放数据的模块,实质上是一个链表的结构,链表的特点也就是增删快,查询修改慢,所以优化查询的效率是必须的,正是因为有序,在查找的时候,从头到后都是有效查找,没有任何一个查找是浪费的(这一点在后面感受)

通过页模式,MySQL 查询时会将一整页数据(16KB)加载到内存,以此减少硬盘 IO 次数、提升性能。

但页模式内部采用链表结构,本质上需通过逐条数据比较定位目标。若表数据量大,且目标数据位于最后一个 page 的最后一条,仍需遍历全表,导致查找速度过慢。
在这里插入图片描述

3.3 页目录

在课本中查找知识点时,我们会选择优先查看目录,找到具体的页,再从页中查找知识点,这样的查找效率要比从头开始找,高效的多。在这里每一个独立的page或每一行数据,都可以视为“页”,而我们要做的是,给这些“页”添加属于他们的目录。
page内部:
在这里插入图片描述
现在,要在一个Page内部,查找id=3记录,直接通过目录2[3],直接进行定位新的起始位置,提高了效率。现在我们可以再次正式回答上面的问题了,为何通过键值 MySQL 会自动排序?可以很方便引入目录,提高查找效率

图中是为了迎合上面的数据,在实际情况下目录间的区间是很大的,在进行目录查找时,一次查找可以pass掉很多数据。

多page情况:
单表数据不断被插入的情况下, MySQL 会在容量不足的时候,自动开辟新的Page来保存新的数据,然后通过指针的方式,将所有的Page组织起来。

上面的方法帮我们提高了表内部遍历数据的效率,但是仍需要将每个page都,加载值内存中,为了进一步减少IO操作,我们采用页目录的方式
在这里插入图片描述
依照这个思路,我们还可以对目录页再次添加目录管理,现在可以得出结论:

  • Page分为目录页和数据页。目录页只放各个下级Page的最小键值。
  • 查找的时候,自定向下找,只需要加载部分目录页到内存,即可完成算法的整个查找过程,大大减少了IO次数
    这个结构最终就是一颗B+树,整个过程中我们所要IO的次数,就是整个结构数的高度

目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址。

3.3 对比其他结构

InnoDB 在建立索引结构来管理数据的时候,其他数据结构为何不行?

  • 链表?线性遍历
  • 二叉搜索树?退化问题,可能退化成为线性结构
  • AVL &&红黑树?虽然是平衡或者近似平衡,但是毕竟是二叉结构,相比较多阶B+树,意味着树整体过高,大家都是自顶向下找,层高越低,意味着系统与硬盘更少的IO Page交互。
  • Hash?官方的索引实现方式中, MySQL 是支持HASH的,不过 InnoDB 和 MyISAM 并不支持Hash跟进其算法特征,决定了虽然有时候也很快(O(1)),不过,在面对范围查找就明显不行。

B树?最值得比较的是 InnoDB 为何不用B树作为底层索引?
B树节点,既有数据,又有Page指针,而B+,只有叶子节点有数据,其他目录页,只有键值和Page指针B+,叶子节点,全部相连,而B没有,为何选择B+
节点不存储data,这样一个节点就可以存储更多的key。可以使得树更矮,所以IO操作次数更少。叶子节点相连,更便于进行范围查找

具体结构特征,你可以搜点图片理解

四、聚簇索引 VS 非聚簇索引

MyISAM 引擎同样使用B+树作为索引结果,叶节点的data域存放的是数据记录的地址。下图为MyISAM表的主索引,Col1 为主键
在这里插入图片描述
其中,MyISAM最大的特点是,将索引Page和数据Page分离,也就是叶子节点没有数据,只有对应数据的地址相较于InnoDB索引,InnoDB是将索引和数据放在一起的。
现在我们就可以回答,第一篇文章遗留的问题了

innodb引擎
create table itest(
id int primary key,
name varchar(11) not null
)engine=InnoDB;
MyISAM引擎
create table mtest(
id int primary key,
name varchar(11) not null
)engine=MyISAM;

在这里插入图片描述

MyISAM 这种用户数据与索引数据分离的索引方案,叫做非聚簇索引,InnoDB 这种用户数据与索引数据在一起索引方案,叫做聚簇索引。

MySQL 除了默认会建立主键索引外,我们用户也有可能建立按照其他列信息建立的索引,一般这种索引可以叫做辅助(普通)索引。对于MyISAM ,建立辅助(普通)索引和主键索引没有差别,无非就是主键不能重复,而非主键可重复。
下图就是基于 MyISAM 的 Col2 建立的索引,和主键索引没有差别
在这里插入图片描述
同时我们以上表中的 Col3 建立对应的辅助索引如下图:
在这里插入图片描述
MyISAM 的非主键索引中叶子节点并没有数据,而只有对应记录的key值。
所以通过辅助(普通)索引,找到目标记录,需要两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。这种过程,就叫做回表查询为何MyISAM 针对这种辅助(普通)索引的场景,不给叶子节点也附上数据呢?原因就是太浪费空间了。
那么普通索引为什么要存在呢?
当我们以符合间进行索引时如:(姓名,qq),只知道第一个键值,需要查找第二个键值,我们就可以直接查找:
在这里插入图片描述
对于复合索引,匹配原则是,从做到右的,也就是说,我们只需要知道姓名,就可以得到qq,这种普通索引方式,要比主键索引更快。

五、索引操作

5.1 创建主键索引

// 在创建表的时候,直接在字段名后指定 primary key
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);

主键索引的特点:

  • 一个表中,最多有一个主键索引,当然可以使符合主键
  • 主键索引的效率高(主键不重复)
  • 创建主键索引的列,它的值不能为null,且不能重复
  • 主键索引的列基本上是int

这些特点,在介绍主键时都说过,只是当时没有提出索引的概念

5.2 唯一索引的创建

//在表定义时,在某列后直接指定unique唯一属性。
create table user4(id int primary key, name varchar(30) unique);//创建表时,在表的后面指定某列或某几列为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);

唯一索引的特点

  • 一个表中,可以有多个唯一索引
  • 查询效率高
  • 如果在某一列建立唯一索引,必须保证这列不能有重复数据
  • 如果一个唯一索引上指定not null,等价于主键索引

5.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); //创建一个索引名为 idx_name 的索引
create table user10(id int primary key, name varchar(20),email varchar(30));create index idx_name on user10(name);

普通索引的特点:

  • 一个表中可以有多个普通索引,普通索引在实际开发中用的比较多
  • 如果某列需要创建索引,但是该列有重复的值,那么我们就应该使用普通索引

5.4 查询索引

show keys from 表名;show index from 表名;

在这里插入图片描述

5.5 删除索引

//删除主键索引 
alter table 表名 drop primary key;//其他索引的删除
alter table 表名 drop index 索引名; drop index 索引名 on 表名

在这里插入图片描述
余下指令你自己测试吧

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

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

相关文章

GitHub 热榜项目 - 日榜(2025-08-24)

GitHub 热榜项目 - 日榜(2025-08-24) 生成于:2025-08-24 统计摘要 共发现热门项目:20 个 榜单类型:日榜 本期热点趋势总结 本期GitHub热榜呈现三大技术热点:1)AI应用爆发式创新,包括神经拟真伴侣&#…

纯净Win11游戏系统|24H2专业工作站版,预装运行库,无捆绑,开机快,游戏兼容性超强!

哈喽,大家好! 今天给大家带来一款 Windows 11 游戏版本系统镜像,软件已放在文章末尾,记得获取。 一、软件获取与启动 解压后双击exe即可直接运行,无需额外安装。首次启动界面简洁,引导清晰。 二、系统选…

CI/CD 学习之路

目录 简介: 1、工具介绍: 2、搭建jenkins 1)创建一个文件Dockerfile,文件无后缀,写入以下代码 2)在Dockerfile文件所在目录执行(my-jenkins-android 未自定义镜像名称) 3&#xf…

马斯克宣布开源Grok 2.5:非商业许可引争议,模型需8×40GB GPU运行,Grok 3半年后开源

昨晚,马斯克在 X 平台连续发布多条消息,宣布其人工智能公司 xAI 已正式开源 Grok 2.5 模型。这款模型是 xAI 在 2024 年的主力模型,如今完全向公众开放。与此同时,马斯克还预告了下一代模型 Grok 3 的开源计划,预计将在…

DMP-Net:面向脑组织术中成像的深度语义先验压缩光谱重建方法|文献速递-深度学习人工智能医疗图像

Title题目DMP-Net: Deep semantic prior compressed spectral reconstruction methodtowards intraoperative imaging of brain tissueDMP-Net:面向脑组织术中成像的深度语义先验压缩光谱重建方法01文献速递介绍脑肿瘤可分为原发性和继发性两类。原发性脑肿瘤多发生…

【nl2sql综述】2025最新综述解读

论文地址:https://arxiv.org/pdf/2408.05109 解读:迈向数据民主化——大型语言模型时代下的Text-to-SQL技术综述 近期,一篇名为《A Survey of Text-to-SQL in the Era of LLMs》的综述论文系统性地梳理了自然语言到SQL查询(Text-t…

logback-spring.xml 文件

一.概述这是一个日志文件,主要用来对应用程序的日志进行记录,并且可以配置日志的一些格式和规则。二.读取机制1.SpingBoot自动识别进行文件扫描时,当在 classpath 下发现名为 logback-spring.xml 的文件时,Spring Boot 会自动加载…

LeetCode Hot 100 第二天

1. 283 移动零 链接&#xff1a;题目链接 题解&#xff1a; 要求&#xff1a;时间复杂度 < O (n^2) 题解&#xff1a;将非零元素依次往前移&#xff08;占据0元素的位置&#xff09;&#xff0c;最后再将0元素填充至数组尾。时间复杂度O(n)&#xff0c;用一个指针x来维护非…

04-Maven工具介绍

文章目录1、Maven官网2、Maven的3个重要功能3、Maven安装3.1 安装教程的视频3.2 安装教程的文本1、Maven官网 https://maven.apache.org/ 2、Maven的3个重要功能 黑马程序员JavaWeb基础教程&#xff0c;Java web从入门到企业实战完整版 3、Maven安装 3.1 安装教程的视频 …

基于开源 AI 智能名片链动 2+1 模式 S2B2C 商城小程序的新开非连锁品牌店开业引流策略研究

摘要&#xff1a;本文聚焦于一家新开且地理位置优越、目标客户为周边“80 后”“90 后”上班族的非连锁品牌店。在明确店铺定位、完成店内设计与菜品规划等基础工作后&#xff0c;探讨如何在新店开业初期有效打响品牌、吸引目标客户。通过引入开源 AI 智能名片链动 21 模式 S2B…

UE5多人MOBA+GAS 54、用户登录和会话创建请求

文章目录创建主菜单需要的创建主菜单游戏模式创建主菜单游戏控制器创建主菜单界面UI实现登录游戏实例创建等待界面配置和获取协调器 URL撰写和发送会话创建请求创建主菜单需要的 创建主菜单游戏模式 MainMenuGameMode 创建主菜单游戏控制器 MainMenuPlayerController #p…

SCSS上传图片占位区域样式

_App.scss// 上传图片占位区域样式---------------------------------------- [theme"uploadImage"] {transition: 0.2s;position: relative;cursor: pointer;border-radius: 4px;/*居中填满*/background-repeat: no-repeat;background-position: center;background-…

Prometheus+Grafana监控mysql

1、简述 使用 Prometheus 结合 Grafana 监控 MySQL 是一套成熟且广泛应用的方案&#xff0c;能实现对 MySQL 性能、状态等指标的实时采集、存储、可视化及告警。 2、整体架构说明 Prometheus&#xff1a;负责定时从 MySQL 采集监控指标&#xff08;需借助 Exporter&#xff0…

网络流量分析——Tcpdump 数据包过滤

文章目录.PCAP 文件Tcpdump 数据包过滤过滤和高级语法选项有用的 TCPDump 过滤器主机过滤器源/目标过滤器使用源和端口作为过滤器将目标与网络过滤器结合使用协议过滤器 - 通用名称协议过滤器 - 编号端口过滤器端口范围过滤器小于/大于过滤器利用更大的AND 过滤器无滤镜的基本捕…

DeepSeek V3.1 横空出世:重新定义大语言模型的边界与可能

当大语言模型领域的竞争进入白热化阶段&#xff0c;一场静默的技术革命正在悄然酝酿。2025 年8月19日&#xff0c;DeepSeek 团队带着全新升级的 V3.1 版本强势登场&#xff0c;这个被业内称为 “智能体时代敲门砖” 的模型&#xff0c;究竟藏着多少颠覆认知的黑科技&#xff1f…

Unity Netcode for GameObjects(多人联机小Demo)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、安装 Netcode for GameObjects二、做个小Dome1.NetcodeManageNet2.创建UI3.创建预制体4.代码介绍UI代码随机位置代码总结前言 Netcode for GameObjects 是 …

Ant Design for UI 选择下拉框

1. 单选框 与多选框<template><div class"demo-page" style"padding: 40px; max-width: 1200px; margin: 0 auto; font-family: Microsoft YaHei, Arial, sans-serif;"><h1 style"color: #1890ff; text-align: center; margin-bottom…

动手学深度学习01-引言

动手学深度学习pytorch 参考地址&#xff1a;https://zh.d2l.ai/ 文章目录动手学深度学习pytorch1-第01章-引言1. 机器学习/深度学习基础1.1 什么是机器学习&#xff1f;1.2 深度学习与机器学习的关系&#xff1f;2. 数据&#xff08;Data&#xff09;2.1 什么是样本、特征、标…

大模型提示词工程背后的原理:深入理解Prompt Learning(提示学习)

“ 知其然也要知其所以然&#xff0c;为什么会有提示词工程&#xff1f;” 了解和使用过大模型的人应该都知道提示词工程&#xff0c;即使不了解提示词工程&#xff0c;至少也应该听说过&#xff0c;提示词工程说白了就是一种和大模型交流的方法&#xff0c;它的作用就是让大模…

AI 智能体安全设计模式:从三大“反模式”看如何构建可信的 AI 系统

摘要&#xff1a;当我们将 AI 智能体&#xff08;Agent&#xff09;从实验原型推向生产环境时&#xff0c;许多团队在不经意间重复着一些危险的错误实践。这些反复出现的错误&#xff0c;在软件工程中被称为“反模式”&#xff08;Anti-Patterns&#xff09;。本文基于 Curity …