MySQL索引介绍

目录

一、索引是什么

[1. 索引的本质](#1. 索引的本质)

[2. 索引的核心作用](#2. 索引的核心作用)

[二、底层原理:MySQL 为何选择 B + 树作为索引结构](#二、底层原理:MySQL 为何选择 B + 树作为索引结构)

[1. 候选数据结构对比](#1. 候选数据结构对比)

[2. B + 树的核心特点](#2. B + 树的核心特点)

[3. B + 树在 MySQL 中的实际应用](#3. B + 树在 MySQL 中的实际应用)

三、索引分类:

[1. 按存储结构分类](#1. 按存储结构分类)

[(1)聚集索引(Clustered Index)](#(1)聚集索引(Clustered Index))

[(2)非聚集索引(Secondary Index)](#(2)非聚集索引(Secondary Index))

[2. 按功能分类](#2. 按功能分类)

[(1)主键索引(Primary Key)](#(1)主键索引(Primary Key))

[(2)唯一索引(Unique Index)](#(2)唯一索引(Unique Index))

[(3)普通索引(Normal Index)](#(3)普通索引(Normal Index))

[(4)复合索引(Composite Index)](#(4)复合索引(Composite Index))

[(5)全文索引(Fulltext Index)](#(5)全文索引(Fulltext Index))

四、原理与优化

[1. B + 树索引的优势](#1. B + 树索引的优势)

[2. 聚集索引与非聚集索引的核心区别](#2. 聚集索引与非聚集索引的核心区别)

[3. 索引使用的关键原则](#3. 索引使用的关键原则)

(1)索引覆盖:避免回表的高效查询

[(2)复合索引的 "最左前缀原则"](#(2)复合索引的 “最左前缀原则”)

[(3)索引的 "优缺点" 与使用边界](#(3)索引的 “优缺点” 与使用边界)


一、索引是什么

1. 索引的本质

MySQL 的索引是一种排好序的数据结构,它通过特定规则组织数据表中的记录,指向数据行的物理位置,从而实现快速定位和访问数据。

类比生活场景:索引就像汉语字典的目录 ------ 无需逐页查找,通过拼音、笔画等索引就能快速定位目标汉字;数据库中无需全表扫描,通过索引就能直接找到数据所在位置,大幅提升查询效率。

2. 索引的核心作用

核心目标:提升数据检索效率(查询操作占比远高于增删改,索引对查询的优化效果最显著)。

辅助价值:排序时可直接利用索引的有序性,避免额外排序操作。

二、底层原理:MySQL 为何选择 B + 树作为索引结构

MySQL 支持多种数据结构作为索引基础,但最终选择B + 树作为默认索引结构。要理解这一点,需先对比其他候选结构的优缺点:

1. 候选数据结构对比

|------------------|------------------|--------------------------|
| 数据结构 | 优点 | 缺点 |
| HASH | 单值查询速度快(O (1)) | 不支持范围查询、排序操作 |
| 二叉搜索树 | 中序遍历有序 | 最坏情况树高为 N(O (N)),IO 次数过多 |
| AVL / 红黑树(平衡二叉树) | 树高平衡(O (logN)) | 二叉结构导致树高仍较高,IO 次数较多 |
| N 叉树 | 降低树高,减少 IO 次数 | 非叶子节点存储数据,空间利用率低 |
| B + 树(最终选择) | 树高最低、支持范围查询、性能均衡 | |

2. B + 树的核心特点

  • 非叶子节点仅存索引信息,不存真实数据;所有真实数据都存储在叶子节点。
  • 叶子节点构成有序双向链表 ,天然支持范围查询(如between andorder by)。
  • 相同数据量下树高最低,磁盘 IO 次数最少(数据库性能瓶颈是磁盘 IO,减少 IO 即提升性能)。
  • 查找任一元素的时间复杂度均为 O (logN),性能均衡,无极端情况。

3. B + 树在 MySQL 中的实际应用

MySQL 中数据存储的最小单元是页(Page),默认大小 16KB,页与页之间通过双向链表连接,页内数据通过单向链表组织。

B + 树与页结构的结合逻辑:

  • B + 树的非叶子节点对应 "索引页",存储索引键和下一级页的地址(8 字节主键 + 6 字节页地址 = 14 字节 / 条,16KB 页可存约 1170 条索引)。
  • B + 树的叶子节点对应 "数据页",存储完整的行数据(16KB 页可存约 16 条 1KB 大小的行数据)。
  • 检索过程:从根节点开始,通过索引键比较定位到子节点页,最终在叶子节点页中找到目标数据。例如三层 B + 树可存储约 2190 万条数据,仅需 3 次磁盘 IO 即可完成检索。

三、索引分类:

MySQL 的索引按功能和存储方式可分为多种类型,核心分类如下:

1. 按存储结构分类

(1)聚集索引(Clustered Index)

**核心特点:**索引与数据 "聚簇" 存储,索引结构即数据存储结构,叶子节点直接存储完整行数据

生成规则:

表有主键时,主键索引即为聚集索引;

无主键时,选择第一个非空唯一索引作为聚集索引;

既无主键也无合适唯一索引时,MySQL 自动生成 6 字节 ROW_ID 作为隐藏聚集索引。

**优势:**查询主键时无需回表,直接获取完整数据。

(2)非聚集索引(Secondary Index)

**核心特点:**索引与数据分离存储,叶子节点存储 "索引键 + 主键值",需通过主键值回表查询完整数据(此过程称为 "回表")。

**常见类型:**普通索引、唯一索引、全文索引、复合索引等。

**注意:**非聚集索引依赖聚集索引,删除聚集索引会导致所有非聚集索引失效。

2. 按功能分类

(1)主键索引(Primary Key)

特点:唯一且非空,自动成为聚集索引。

创建方式:

sql 复制代码
-- 方式1:建表时指定
CREATE TABLE t_test_pk (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(20)
);

-- 方式2:建表后修改
ALTER TABLE t_test_pk2 ADD PRIMARY KEY (id);
(2)唯一索引(Unique Index)

特点:索引列值唯一(允许 NULL 值),可避免重复数据。

创建方式:

sql 复制代码
CREATE TABLE t_test_uk (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(20) UNIQUE -- 建表时创建
);

-- 建表后添加
ALTER TABLE t_test_uk2 ADD UNIQUE (name);
(3)普通索引(Normal Index)

特点:最基础的索引类型,无唯一性限制,仅用于提升查询效率。

创建方式:

sql 复制代码
-- 方式1:建表时指定
CREATE TABLE t_test_index (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  sno VARCHAR(10),
  INDEX (sno)
);

-- 方式2:单独创建并指定索引名
CREATE INDEX idx_sno ON t_test_index2(sno);
(4)复合索引(Composite Index)

特点:基于多列创建的索引,遵循 "最左前缀原则"(查询需匹配索引列的左起顺序)。

适用场景:频繁按多列组合查询(如**WHERE sno = '1001' AND class_id = 2**)。

创建方式:

sql 复制代码
CREATE TABLE t_test_composite (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  sno VARCHAR(10),
  class_id BIGINT,
  INDEX idx_sno_class (sno, class_id) -- 复合索引:sno在前,class_id在后
);
(5)全文索引(Fulltext Index)

特点:基于文本列(CHAR、VARCHAR、TEXT)创建,用于全文搜索(如关键词匹配)。

限制:仅 MyISAM 和 InnoDB 引擎支持。

四、原理与优化

1. B + 树索引的优势

  • 磁盘 IO 效率高:树高低(三层树可存 2000 万 + 数据),查询仅需 3 次 IO。
  • 支持范围查询:叶子节点有序链表,可快速遍历区间数据。
  • 性能均衡:任一元素查询时间复杂度均为 O (logN),无极端情况。
  • 空间利用率高:非叶子节点仅存索引信息,一页可存储更多索引条目。

2. 聚集索引与非聚集索引的核心区别

3. 索引使用的关键原则

(1)索引覆盖:避免回表的高效查询

当查询的列刚好是索引列(或复合索引的所有列)时,无需回表,直接从索引中获取数据,称为 "索引覆盖"。

回表查询是指非聚集索引查询时,叶子节点仅存主键,需通过主键再次查询聚集索引获取完整数据的过程。避免方式:①使用索引覆盖(查询列仅包含索引列);②将高频查询列纳入复合索引。

示例:复合索引**idx_sno_class(sno, class_id)** ,查询**SELECT sno, class_id FROM t_test WHERE sno = '1001'**,直接通过索引返回结果,无需回表。

(2)复合索引的 "最左前缀原则"

复合索引的查询需匹配左起顺序,否则无法命中索引。

示例:索引**idx_sno_class(sno, class_id)**:

  • 命中索引:WHERE sno = '1001'WHERE sno = '1001' AND class_id = 2
  • 未命中索引:WHERE class_id = 2WHERE sno LIKE '%1001'
(3)索引的 "优缺点" 与使用边界

优点:提升查询效率(从全表扫描 O (N) 到 O (logN))、支持排序和分组;

缺点:占用额外存储空间、增删改操作需维护索引(降低写入效率);

禁忌:不要过度建索引(一张表建议不超过 5 个)、不要在低频查询列建索引、不要在大字段(如 TEXT)建索引。

相关推荐
ʚB҉L҉A҉C҉K҉.҉基҉德҉^҉大3 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python
哈__3 小时前
多模融合 一体替代:金仓数据库 KingbaseES 重构企业级统一数据基座
数据库·重构
老邓计算机毕设3 小时前
SSM医院病人信息管理系统e7f6b(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·医院信息化·ssm 框架·病人信息管理
2601_949613023 小时前
flutter_for_openharmony家庭药箱管理app实战+药品分类实现
大数据·数据库·flutter
dyyx1114 小时前
使用Scikit-learn进行机器学习模型评估
jvm·数据库·python
踢足球09295 小时前
寒假打卡:2026-01-27
数据库
weixin_499771555 小时前
使用Seaborn绘制统计图形:更美更简单
jvm·数据库·python
青春男大5 小时前
Redis和RedisTemplate快速上手
java·数据库·redis·后端·spring·缓存
冉冰学姐5 小时前
SSM医院预约挂号管理系统q9ig2(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·毕业设计·医院预约挂号系统·ssm 框架