MySQL强化关键_017_索引
目 录
一、概述
二、索引
1.主键索引
2.唯一索引
3.查看索引
4.添加索引
(1)建表时添加
(2)建表后添加
5.删除索引
三、树
1.二叉树
2.红黑树
3.B树
4.B+树
(1)为什么 MySQL 选择B+树作为索引数据结构,而不是B树?
(2) 表中没有主键索引,还会创建B+树吗?
四、Hash 索引
五、聚集索引和非聚集索引
六、二级索引
七、覆盖索引
八、索引下推
九、单列索引和复合索引
一、概述
- 索引是一种能够提高检索效率的有序的数据结构;
- 索引是解决 SQL 慢查询的一种方式;
- 不同的存储引擎有不同的索引类型;
- 分类:
- 数据结构分类:
- B+树 索引:采用 B+树的数据结构,MySQL 的 InnoDB 存储引擎采用该索引;
- Hash 索引:采用哈希表的数据结果,MySQL 仅 MEMORY 存储引擎支持。
- 物理存储分类:
- 聚集索引:索引和表中数据在一起,存储时按照索引顺序存储,一张表只能有一个聚集索引;
- 非聚集索引:索引和表中数据分离,索引独立于表空间,一张表可以有多个非聚集索引。
- 字段特性分类:
- 主键索引;
- 唯一索引;
- 普通索引;
- 全文索引:字段类型都是文本内容才可以使用,仅 InnoDB 和 MyISAM 存储引擎支持。
- 字段个数分类:
- 单列索引(单一索引);
- 联合索引(复合索引、组合索引)。
- 优点:
- 提高查询性能:通过创建索引,大大降低了数据库查询的数据量;
- 加速排序;
- 减少 I/O 开销。
- 缺点:
- 占据额外的存储空间;
- 增、删、改操作性能损耗:每次对表进行修改操作,都需要更新索引;
- 资源消耗大:索引需要占用内存和 CPU 资源,特别是在大规模并发访问情况下。
- 建议使用索引的场景:
- 频繁执行查询操作的字段;
- 表数据量较大;
- 需要排序或分组的字段;
- 外键关联的字段。
- 不建议使用索引的场景:
- 频繁执行更新操作的表;
- 表数据量较小;
- 唯一性很差的字段。
二、索引
1.主键索引
主键字段会自动添加索引,被称为主键索引。
2.唯一索引
unique 约束的字段会自动添加索引,被称为唯一索引。
3.查看索引
show index from 表名;
4.添加索引
(1)建表时添加
create table 表名(
字段 类型,
……,
index 索引名(字段名)
);
drop table if exists pet;create table pet(id int primary key auto_increment,no bigint unique,name varchar(10),age char(2),sex char(2),index pet_index(name)
);show index from pet;
(2)建表后添加
- alter table 表名 add index 索引名(字段);
- create index 索引名 on 表名(字段名);
drop table if exists pet;create table pet(id int primary key auto_increment,no bigint unique,name varchar(10),age char(2),sex char(2),
);-- 第一种方式
alter table pet add index pet_index_name(name);-- 第二种方式
create index pet_index_age on pet(age);show index from pet;
5.删除索引
alter table 表名 drop index 索引名;
alter table pet drop index pet_index_age;
alter table pet drop index pet_index_name;show index from pet;
三、树
开始前,推荐一个数据结构可视化平台【Data Structure Visualization】。
1.二叉树
id | name |
---|---|
50 | 后羿 |
43 | 鲁班七号 |
28 | 伽罗 |
56 | 艾琳 |
54 | 李元芳 |
66 | 孙尚香 |
78 | 狄仁杰 |
76 | 虞姬 |
假设存储有一张表如上,若不为 id 字段添加索引,则默认进行全表扫描。若要查询 id = 76 的英雄姓名,至少要进行 8 次 I/O 开销。
为了提高效率,可以为 id 字段添加索引,假设使用了二叉树的数据结构,则只需要 5 次便可查找到 76。
但是,如果遇到一种极端情况如下图,所有 id 都是有序排列的,其查找效率等同于链表查询,时间复杂度是 O(n)。所以,MySQL 没有选择二叉树作为索引数据结构。
2.红黑树
通过自旋平衡规则进行旋转,子节点会自动分叉为 2 个分支,从而降低树的高度。数据有序插入时比二叉树数据检索性能更好。
- 红黑树有以下特点:左根右,根叶黑,不红红,黑路同。
- 左根右:左子树小于根节点,右子树大于根节点;
- 根叶黑:根节点是黑色,所有叶子节点也是黑色;
- 不红红:红色节点的子节点必须是黑色;
- 黑路同:从任意节点到其叶子节点的路径上,黑色节点的数量相同。
- 若查找 id = 76 英雄的姓名,则需要进行 4 次 I/O 开销。效率较普通二叉树高,但当数据量庞大时,树的高度会很高,查询效率也较低。所以,MySQL 也没有采用红黑树作为索引数据结构。
3.B树
- B树是自平衡树,又称为平衡多路查找树;
- 每个节点下的子节点数量大于 2;
- 每个节点 可以存储多个数据;
- 3 阶 B树,一个节点下最多可以有 3 个子节点,每个节点最多有 2 个数据;
- 4 阶 B树,一个节点下最多可以有 4 个子节点,每个节点最多有 3 个数据;
- 每个节点不仅存储了索引值,还存储了索引值对应的数据行;
- 但是 B树 不适合区间查找。
4.B+树
- B+树 将数据都存储在了叶子节点,且叶子节点之间使用链表连接;
- B+树 非叶子节点上只有索引值,所以非叶子节点可以存储更多的索引值,从而提高检索效率;
- MySQL 采用 16 阶B+树作为索引数据结构。
(1)为什么 MySQL 选择B+树作为索引数据结构,而不是B树?
答:
1.非叶子节点可以存储更多的键值,阶数可以更大,减少 I/O 开销,提高检索效率;
2.所有数据都是有效存储在叶子节点上的,分组查询效率更高;
3.数据页之间、数据记录之间采用链表连接,升序、降序操作更方便。
(2) 表中没有主键索引,还会创建B+树吗?
答:会的。若一张表没有主键索引,默认会使用一个隐藏的内置聚集索引。该聚集索引基于表的物理存储顺序构建,通常使用B+树实现。
四、Hash 索引
- 支持 Hash 索引的存储引擎:
- InnoDB:不支持手动创建,系统自动维护一个自适应的 Hash 索引。即使手动指定某字段采用 Hash 索引,最终查看索引时,索引类型还是B+树;
- MEMORY。
- Hash 索引底层是 Hash 表。一个数组,数组中每个元素是链表。和 Java 中的 HashMap 一样,Hash 表中每个元素都是 key-value 结构,key 存储索引值,value 存储行指针;
- 优点:只能用于等值比较,效率很高;
- 缺点:不支持排序,不支持范围查找;
- 关于 Hash 表的更多内容可以查看【Java基础关键_021_集合(五)】。
五、聚集索引和非聚集索引
- 按照数据的物理存储方式不同,可以将索引分为聚集索引和非聚集索引;
- 存储引擎是 InnoDB 的,主键上的索引属于聚集索引;存储引擎是 MyISAM 的,任意字段上的索引都是非聚集索引;
- InnoDB 的物理存储方式,在硬盘上生成以下文件:
- [ 表名 ].ibd(InnoDB data 表索引 + 数据);
- [ 表名 ].frm(存储表结构信息)。
- MyISAM 的物理存储方式,在硬盘上生成以下文件:
- [ 表名 ].MYD(表数据);
- [ 表名 ].MYI(表索引);
- [ 表名 ].frm(表结构)。
- MySQL 8.0 开始,不再生成 frm 文件,引入了数据字典,用数据字典统一存储表结构信息;
- 聚集索引优点是:将数据存储在索引树的叶子节点上,可以减少一次查询,因为查询索引树的同时可以获取数据;缺点是:对数据进行修改或删除时需要更新索引树,会增加系统开销。
六、二级索引
- 二级索引属于非聚集索引,也称为辅助索引;
- 所有非主键索引都是二级索引;
- 叶子节点上存储的是一行记录的主键值,而不是这一行数据;
- 使用【select * 】会产生“回表”,即回到原数据表。所以尽量避免使用【select * 】语句,以此提升执行效率。
七、覆盖索引
- 覆盖索引指某个查询语句可以通过索引覆盖完成,不需要“回表”查询真实数据;
- 覆盖指在执行查询语句时,查询需要的所有列都可以从索引中提取到,不需要再去查询实际数据行获取查询所需数据;
- 创建覆盖索引需要考虑查询字段的选择,若查询需要的字段较多,可能需要创建包含多列的覆盖索引。
八、索引下推
- 一般情况下,索引下推是 MySQL 优化器自动处理的;
- 索引下推是 MySQL 中的一种优化方法,可以将查询中的过滤条件下推到索引层级中处理,从而减少回表次数,优化查询效率;
- 在使用索引下推时,MySQL 会在索引的叶节点层级执行查询的过滤条件,过滤掉无用的索引记录,仅返回符合条件的记录的主键,如此可以避免查询时回表读取表格的数据行。
九、单列索引和复合索引
- 单列索引是对数据库表中某一列或属性创建索引,对该列进行快速查找和排序操作;
- 复合索引是对数据库表中多个列创建索引;
- 最左前缀原则:复合索引中,索引最左边的列会被优先使用;
- 复合索引较单列索引的优势:
- 减少索引的数量;
- 提高查询性能;
- 覆盖查询:如果复合索引包含了所有查询需要的列,则数据库可以直接使用索引中的数据;
- 提高排序和分组性能。
相关文章:

MySQL强化关键_017_索引
目 录 一、概述 二、索引 1.主键索引 2.唯一索引 3.查看索引 4.添加索引 (1)建表时添加 (2)建表后添加 5.删除索引 三、树 1.二叉树 2.红黑树 3.B树 4.B树 (1)为什么 MySQL 选择B树作为索引…...
stm32——SPI协议
stm32——SPI协议 STM32的SPI(Serial Peripheral Interface,串行外设接口)协议是一种高速、全双工、同步的串行通信协议,广泛评估微控制器与各种外设(如传感器、器件、显示器、模块等)之间的数据传输。STM3…...
Linux 下如何查看进程的资源限制信息?
简介 Linux 上的 cat /proc/$pid/limits 命令提供有关特定进程的资源限制的信息,其中 $pid 是相关进程的进程 ID (pid)。该文件是 /proc 文件系统的一部分,该文件系统是一个虚拟文件系统,提供有关进程和系统资源的信息…...

【备忘】php命令行异步执行超长时间任务
环境说明: 操作系统:windows10 IDE:phpstorm 开发语言:php7.4 框架:thinkphp5.1 测试环境:linuxwindows均测试通过。 初级方法: function longRunningTask() {$root_path Tools::get_ro…...
对于ARM开发各种手册的分类
手册名称全称主要内容适用范围是不是讲SysTick?Cortex-M3 Technical Reference Manual (TRM)Cortex-M3 Technical Reference Manual描述 Cortex-M3内核架构,如寄存器模型、总线接口、指令集、异常模型只适合 Cortex-M3 内核,不含外设❌ 没有C…...
java开发中#和$的区别
在Spring框架中,$ 和 # 是两种不同的表达式前缀,用于从不同的来源获取值或执行计算。下面详细解释它们的区别和用法: 一、$ 占位符(Property Placeholder) 1. 作用 从配置文件(如 application.propertie…...

在 RK3588 上通过 VSCode 远程开发配置指南
在 RK3588 上通过 VSCode 远程开发配置指南 RK3588 设备本身不具备可视化编程环境,但可以通过 VSCode 的 Remote - SSH 插件 实现远程代码编写与调试。以下是完整的配置流程。 一、连接 RK3588 1. 安装 Debian 系统 先在 RK3588 上安装 Debian 操作系统。 2. 安…...

OpenHarmony标准系统-HDF框架之音频驱动开发
文章目录 引言OpenHarmony音频概述OpenHarmony音频框图HDF音频驱动框架概述HDF音频驱动框图HDF音频驱动框架分析之音频设备驱动HDF音频驱动框架分析之supportlibs实现HDF音频驱动框架分析之hdi-passthrough实现HDF音频驱动框架分析之hdi-bindev实现HDF音频驱动加载过程HDF音频驱…...

HTML Day03
Day03 0. 引言1. CSS1.1 CSS的3种使用方法1.2 内联样式1.3 内部样式表1.4 外部CSS文件 2. 图像3. 表格3.1单元格间距和单元格边框 4. 列表4.1 有序表格的不同类型4.2 不同类型的无序表格4.3 嵌套列表 5. 区块6. 布局6.1 div布局6.2 表格布局 0. 引言 HELLO ^ _ ^大家好…...

篇章六 数据结构——链表(二)
目录 1. LinkedList的模拟实现 1.1 双向链表结构图编辑 1.2 三个简单方法的实现 1.3 头插法 1.4 尾插法 1.5 中间插入 1.6 删除 key 1.7 删除所有key 1.8 clear 2.LinkedList的使用 2.1 什么是LinkedList 5.2 LinkedList的使用 1.LinkedList的构造 2. LinkedList的…...
Python60日基础学习打卡Day39
昨天我们介绍了图像数据的格式以及模型定义的过程,发现和之前结构化数据的略有不同,主要差异体现在2处 模型定义的时候需要展平图像由于数据过大,需要将数据集进行分批次处理,这往往涉及到了dataset和dataloader来规范代码的组织…...

吴恩达MCP课程(3):mcp_chatbot
原课程代码是用Anthropic写的,下面代码是用OpenAI改写的,模型则用阿里巴巴的模型做测试 .env 文件为: OPENAI_API_KEYsk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx OPENAI_API_BASEhttps://dashscope.aliyuncs.com/compatible-mode…...
MySQL访问控制与账号管理:原理、技术与最佳实践
MySQL的安全体系建立在精细的访问控制和账号管理机制上。本文基于MySQL 9.3官方文档,深入解析其核心原理、关键技术、实用技巧和行业最佳实践。 一、访问控制核心原理:双重验证机制 连接验证 (Connection Verification) 客户端发起连接时,MyS…...
AWS 创建VPC 并且添加权限控制
AWS 创建VPC 并且添加权限控制 以下是完整的从0到1在AWS中创建VPC并配置权限的步骤(包含网络配置、安全组权限和实例访问): 1. 创建VPC 步骤: 登录AWS控制台 访问 AWS VPC控制台,点击 创建VPC。 配置基础信息 名称…...
langchain学习 01
dotenv库:可以从.env文件中加载配置信息。 from dotenv import load_dotenv # 加载函数,之后调用这个函数,即可获取配置环境.env里面的内容: deep_seek_api_key<api_key>getpass库:从终端输入password性质的内…...

【清晰教程】查看和修改Git配置情况
目录 查看安装版本 查看特定配置 查看全局配置 查看本地仓库配置 设置或修改配置 查看安装版本 打开命令行工具,通过version命令检查Git版本号。 git --version 如果显示出 Git 的版本号,说明 Git 已经成功安装。 查看特定配置 如果想要查看特定…...

JAVA 常用 API 正则表达式
1 正则表达式作用 作用一:校验字符串是否满足规则作用二:在一段文本中查找满足要求的内容 2 正则表达式规则 2.1 字符类 package com.bjpowernode.test14;public class RegexDemo1 {public static void main(String[] args) {//public boolean matche…...

光电设计大赛智能车激光对抗方案分享:低成本高效备赛攻略
一、赛题核心难点与备赛痛点解析 全国大学生光电设计竞赛的 “智能车激光对抗” 赛题,要求参赛队伍设计具备激光对抗功能的智能小车,需实现光电避障、目标识别、轨迹规划及激光精准打击等核心功能。从历年参赛情况看,选手普遍面临三大挑战&a…...

Python实现P-PSO优化算法优化BP神经网络回归模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在当今数据驱动的时代,回归分析作为预测和建模的重要工具,在科学研究和工业应用中占据着重要…...

Microsoft的在word中选择文档中的所有表格进行字体和格式的调整时的解决方案
找到宏 创建 并粘贴 使用 Sub 全选所有表格() Dim t As Table an MsgBox("即将选择选区内所有表格,若无选区,则选择全文表格。", vbYesNo, "reboot提醒您!") If an - 6 Then Exit Sub Set rg IIf(Selection.Type wdSelectionIP, …...

C++23:关键特性与最新进展深度解析
文章目录 范围的新功能与增强元组的优化与新特性字符与字符串的转义表示优化std::thread::id的改进与扩展栈踪迹的格式化支持结论 C23作为C标准的最新版本,带来了许多令人瞩目的改进和新特性。从新的范围和元组功能到对字符和字符串转义表示的优化,再到 …...
Rust并发编程实践指南
Rust并发编程实践指南 一、Rust并发编程哲学 mindmaproot((Rust并发))Ownership System▶ 移动语义▶ 借用规则Type Safety▶ Send Trait▶ Sync TraitZero-Cost Abstraction▶ 无运行时开销▶ 编译期检查Fearless Concurrency▶ 数据竞争预防▶ 死锁检测工具二、核心并发模型…...
Kubernetes资源申请沾满但是实际的资源占用并不多,是怎么回事?
Kubernetes资源申请沾满但是实际的资源占用并不多是Kubernetes资源管理中的一个常见误解。 K8s资源管理机制 资源请求(Requests) vs 实际使用量 从你的截图可以看到: K8s节点资源状态(第一张图): CPU请求量:13795…...

鲲鹏Arm+麒麟V10 K8s 离线部署教程
针对鲲鹏 CPU 麒麟 V10 的离线环境,手把手教你从环境准备到应用上线,所有依赖包提前打包好,步骤写成傻瓜式操作指南。 一、环境规划# 准备至少两台机器。 架构OS作用Arm64任意,Mac 也可以下载离线包Arm64麒麟 V10单机部署 K8s…...

PGSQL结合linux cron定期执行vacuum_full_analyze命令
VACUUM FULL ANALYZE 详解 一、核心功能 空间回收与重组 完全重写表数据文件,将碎片化的存储空间合并并返还操作系统(普通 VACUUM 仅标记空间可重用)。彻底清理死元组(已删除或更新的旧数据行),解…...
php 中使用MQTT
MQTT 是一种基于发布/订阅模式的 轻量级物联网消息传输协议 ,可以用极少的代码和带宽为联网设备提供实时可靠的消息服务,它广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等行业。 本文主要介绍如何在 PHP项目中使用composer require php-m…...

C#定时器深度对比:System.Timers.Timer vs System.Threading.Timer性能实测与选型指南
本文通过真实基准测试揭秘两种常用定时器的性能差异,助你做出最佳选择 一、C#定时器全景概览 在C#生态中,不同定时器适用于不同场景。以下是主流定时器的核心特性对比: 定时器类型命名空间适用场景触发线程精度内存开销依赖框架System.Wind…...
go的select多路复用
传统的方法在遍历管道时,如果不关闭会阻塞而导致 deadlock ,在实际开发中,可能我们不好确定什么关闭该管道。使用select来获取channel里面的数据的时候不需要关闭channel 你也许会写出如下代码使用遍历的方式来实现: for { //…...
深度理解与剖析:前端声明式组件系统
好的,我将根据您的要求,首先进行深度理解与多维思考,然后形成一个全面且有深度的综合性总结,其中包含针对初学者的简洁解释。 1. 核心概念解析:声明式与命令式编程 在深入理解前端的声明式组件系统之前,我…...

解决8080端口被占问题
文章目录 1. 提出问题2. 解决问题2.1 查看占用8080端口的进程2.2 杀死占用8080端口的进程2.3 测试问题是否已解决3. 实战小结1. 提出问题 运行Spring Boot项目,报错8080端口被占 2. 解决问题 2.1 查看占用8080端口的进程 执行命令:netstat -ano | findstr :8080 2.2 杀死占用…...