Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > 索引设计优化

MySQL索引的原理与性能优化设计教程(图文代码)

作者:中环留念

本文详细介绍了索引的分类、功能和实现方式,包括主键索引、唯一索引、常规索引、全文索引以及聚簇索引和非聚簇索引,文章还探讨了索引设计的最佳实践,包括主键选择、索引覆盖等优化策略,为数据库性能优化提供了理论基础

一、前言

索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。

索引的作用就相当于书的目录。打个比方:我们在查字典的时候,如果没有目录,那我们就只能一页一页地去找我们需要查的那个字,速度很慢;如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。

索引底层数据结构存在很多种类型,常见的索引结构有:B 树、 B+ 树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyISAM,都使用了 B+ 树作为索引结构。

二、索引类型划分

按照数据结构维度划分:

按数据结构维度划分的索引类型本文不做详细介绍,本文主要针对以下两种分类做阐述

按“功能/约束”分类:主键索引、唯一索引、常规索引、全文索引

分类含义特点关键字
主键索引针对于表中主键创建的索引默认自动创建, 只能有一个PRIMARY
唯一索引避免同一个表中某数据列中的值重复可以有多个UNIQUE
常规索引快速定位特定数据可以有多个
全文索引全文索引查找的是文本中的关键词,而不是比较索引中的值可以有多个FULLTEXT

按“存储形式/数据组织方式”分类:聚集索引(Clustered)、二级索引(Secondary)

分类含义特点
聚集索引(Clustered Index)将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据必须有,而且只有一个
二级索引(Secondary Index)将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键可以存在多个

三、按功能/约束分类

1.主键索引(PRIMARY KEY)

定义

InnoDB 特点

适用场景

CREATE TABLE users (
  id INT PRIMARY KEY,  -- 主键索引
  username VARCHAR(50)
);

2.唯一索引(UNIQUE)

定义

底层实现

典型用途

CREATE TABLE users (
  id INT PRIMARY KEY,
  mobile VARCHAR(20) UNIQUE,  -- 唯一索引
  email VARCHAR(50) UNIQUE
);

3.常规索引(普通索引 / INDEX)

定义

底层实现

特点

用途

例子:单列索引

ALTER TABLE user ADD INDEX idx_name(name);

例子:联合索引

ALTER TABLE user ADD INDEX idx_name_phone(name, phone);

查询:

SELECT * FROM user WHERE name='Tom' AND phone='138...';

👉 更容易走 (name, phone) 的联合索引。

4.全文索引(FULLTEXT)

定义

实现与特点

例子

CREATE TABLE article (
  id BIGINT PRIMARY KEY,
  title VARCHAR(200),
  content TEXT,
  FULLTEXT KEY ft_content(content)
) ENGINE=InnoDB;

查询:

SELECT * FROM article
WHERE MATCH(content) AGAINST('mysql 索引' IN NATURAL LANGUAGE MODE);

四、按“存储形式/数据组织方式”分类

1.聚簇索引(聚集索引)

聚簇索引:在 InnoDB 存储引擎中,聚簇索引通常就是主键索引 。聚簇索引的特点是数据与索引一体化存储,即数据行(整行,不是指针)直接存储在索引的叶子节点中,并且数据按照主键的顺序进行物理存储 。这使得聚簇索引在查询时具有极高的效率,尤其是对于主键查询和范围查询。因为数据是按照主键顺序存储的,所以在进行范围查询(如查询 ID 在某个范围内的用户)时,可以利用索引的有序性,快速定位到满足条件的数据。此外,聚簇索引还能利用顺序检测预取机制,提高数据读取的效率。例如,在一个用户表中,以用户 ID 为主键创建聚簇索引,当查询用户 ID 为 100 的用户信息时,数据库可以直接通过聚簇索引找到对应的叶子节点,获取用户信息,无需进行额外的查找操作。需要注意的是,一张表只能有一个聚簇索引,因为数据的物理存储顺序只能有一种。

概括:用主键查 = 直接定位到叶子节点 = 一次 B+Tree 查找拿到整行

为什么叫“聚集”

聚集索引选取规则:

聚簇索引的优缺点:

优点

缺点

2.非聚簇索引

也称为二级索引,其索引存储的是主键值,而不是实际的数据行 。当使用非聚簇索引进行查询时,首先会根据索引找到对应的主键值,然后再通过主键值在聚簇索引中查找实际的数据行(整行),这个过程称为回表查询 。非聚簇索引支持多列组合索引,适用于多个字段联合查询的场景。例如,在一个订单表中,经常需要根据客户 ID 和订单日期进行查询,可以为客户 ID 和订单日期创建组合非聚簇索引。虽然非聚簇索引需要回表查询,查询效率相对聚簇索引略低,但在某些情况下,它可以提供更灵活的查询方式。比如,在查询订单表中某个客户在特定日期之后的订单时,通过组合非聚簇索引可以快速定位到满足条件的主键值,然后再通过回表查询获取完整的订单信息。

概括:二级索引的叶子节点存的不是整行,而是“索引列 + 主键值”。

覆盖索引(避免回表)

非聚簇索引的优缺点:

优点

更新代价比聚簇索引要小。非聚簇索引的更新代价就没有聚簇索引那么大了,非聚簇索引的叶子节点是不存放数据的。

缺点

五、图解

1.示例表结构

CREATE TABLE account_example (
  id INT PRIMARY KEY AUTO_INCREMENT COMMENT '账户ID',
  name VARCHAR(20) COMMENT '姓名',
  money DOUBLE(10,2) COMMENT '余额',
  INDEX idx_name (name),
  INDEX idx_name_money (name, money)
) ENGINE=InnoDB;
​
-- 插入数据
insert into account_example(id, name , money)
values
(1, '张三', 100.00),
(3, '李四', 200.00),
(7, '王五', 300.00);

id主键索引(聚簇索引)

idx_name(name)普通二级索引

idx_name_money(name, money)→ 联合索引

2.聚簇索引(id)B+Tree 示意图:

聚簇索引的B+Tree 的叶子节点存放的是整行数据。

特点总结

SELECT * FROM account WHERE id = 3;

👉 一次 B+Tree 查找即可拿到整行数据,不存在回表

3.非聚簇索引(idx_name)的 B+Tree 示意图:

非聚簇索引的叶子节点中:不存整行数据,只存「索引列值 + 主键值」

二级索引的叶子节点下挂的是该字段值对应的主键值。

4.为什么会发生回表

示例 SQL(会回表)

SELECT * FROM account WHERE name = '李四';

执行过程拆解

Step 1:通过二级索引 idx_name 查找

name='李四'
   ↓
在 idx_name B+Tree 中定位
   ↓
得到主键 id = 3

Step 2:根据主键回到聚集索引

id=3
   ↓
在 PRIMARY KEY B+Tree 中查找
   ↓
获取完整行数据

📌 这一步称为:回表

本质原因:二级索引不存完整数据

5.联合索引 idx(name, money) 的存储结构

联合索引叶子节点存:(name, money) + id

idx_name_money(name, money) B+Tree 示意图:

6.覆盖索引 vs 回表

❌ 示例 1:需要回表

SELECT * FROM account
WHERE name = '李四';

✅ 示例 2:覆盖索引(不回表)

SELECT name, money
FROM account
WHERE name = '李四';

📌 这就叫:覆盖索引(Covering Index)

7.总结

场景是否回表原因
where id = ?聚集索引叶子节点存整行
普通二级索引查 *二级索引不存完整数据
联合索引覆盖查询字段查询字段都在索引中
SELECT *几乎一定字段太多,无法覆盖

六、关联

功能分类在 InnoDB 的存储形式
主键索引聚集索引(叶子存整行)
唯一索引通常是 二级索引(除非它被选为聚集索引键)
常规索引二级索引
全文索引倒排索引体系(不按聚集/二级的 B+Tree 逻辑走)

七、问题

主键为什么不要用随机值(如随机 UUID)?

二级索引为什么存主键值,而不是物理地址?

建索引的常见收益点

八、总结

到此这篇关于MySQL索引的原理与性能优化教程的文章就介绍到这了,更多相关索引设计优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文