下面是一份简单明了的 MySQL 索引教程,适合初学者和有一定基础的用户快速上手。
📘 MySQL 索引教程
一、什么是索引?
索引(Index) 是数据库表中的一种数据结构,用于快速查询数据,类似于图书的目录。
它能大大提高 SELECT 查询效率,但也会占用存储空间,并稍微降低 INSERT/UPDATE 的性能。
二、索引的类型
| 类型 | 说明 |
|---|---|
| 主键索引(PRIMARY KEY) | 唯一且不能为空,自动创建索引。 |
| 唯一索引(UNIQUE) | 保证列中的值唯一。 |
| 普通索引(INDEX/KEY) | 最基本的索引,没有唯一性限制。 |
| 组合索引(Composite Index) | 将多个列组成一个索引,适用于多列查询。 |
| 全文索引(FULLTEXT) | 支持文本搜索,主要用于 CHAR, VARCHAR, TEXT 类型的字段(MyISAM/5.6后InnoDB)。 |
三、创建索引的方法
1. 创建表时添加索引
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(100),
email VARCHAR(100) UNIQUE,
age INT,
INDEX idx_username (username)
);
2. 使用 ALTER TABLE 添加索引
-- 添加普通索引
ALTER TABLE users ADD INDEX idx_age (age);
-- 添加唯一索引
ALTER TABLE users ADD UNIQUE idx_email (email);
-- 添加组合索引
ALTER TABLE users ADD INDEX idx_name_age (username, age);
3. 使用 CREATE INDEX
CREATE INDEX idx_username ON users(username);
CREATE UNIQUE INDEX idx_email_unique ON users(email);
四、查看与删除索引
1. 查看索引
SHOW INDEX FROM users;
2. 删除索引
-- 注意:主键索引要用 DROP PRIMARY KEY
DROP INDEX idx_username ON users;
ALTER TABLE users DROP INDEX idx_email;
ALTER TABLE users DROP PRIMARY KEY;
五、索引的使用建议
- ✅ 经常出现在 WHERE、JOIN、ORDER BY 的列应加索引
- ✅ 组合索引中的列顺序要根据查询习惯设计(最左前缀原则)
- ❌ 避免给频繁更新的字段加索引
- ❌ 不要对低选择性的字段(如性别)加索引
- ✅ 全文搜索使用 FULLTEXT 索引
六、常见问题
1. 索引为什么不起作用?
- 查询语句没有使用最左前缀
- 使用了
OR、LIKE '%xxx'等不利于索引的操作 - 数据量太小,优化器认为全表扫描更快
2. 如何分析索引是否使用?
使用 EXPLAIN 关键字:
EXPLAIN SELECT * FROM users WHERE username = 'Tom';
是否需要我为你提供具体的优化案例或实际项目中的索引设计建议?
底层B+tree
是的,MySQL 中索引的底层原理主要是基于树结构,但不是普通的树,而是B+树(B+Tree)。
✅ 一句话总结:
MySQL 的大多数索引(特别是 InnoDB 引擎)是基于 B+树 实现的。
👇 详细解释如下:
1. B+树 vs 二叉树 / 哈希表
- MySQL 不是用二叉树,因为数据量大时树太高,查找慢。
- 也不是哈希表(除非你用的是哈希索引,如 MEMORY 引擎),因为哈希不能范围查找、排序。
- B+树是一种多路平衡查找树,每个节点可以有多个子节点,适合磁盘存储,能减少磁盘 IO。
2. 为什么用 B+树
- 所有值都存在叶子节点,非叶子节点只存键值(更紧凑)
-
叶子节点之间有链表结构,方便做范围查询(比如
BETWEEN、ORDER BY) - 每次查询最多只需 logₙ(N) 次磁盘 I/O,速度非常快
- 可以很好地支持 范围查找、前缀匹配、排序优化
3. InnoDB 中索引的分类
| 类型 | 结构 | 说明 |
|---|---|---|
| 主键索引 | B+树 | 聚簇索引,叶子节点保存完整数据行 |
| 辅助索引(普通索引) | B+树 | 叶子节点保存主键值,不能直接取出行,需要回表 |
| 全文索引 | 倒排索引(不是树) | 用于全文搜索(如 MATCH ... AGAINST) |
| 空间索引 | R-Tree | 用于地理空间数据(GIS) |
4. 举个例子:
假设你有这样一条 SQL:
SELECT * FROM users WHERE age BETWEEN 20 AND 30;
如果 age 字段有 B+树索引:
- MySQL 可以快速定位到
age=20的第一个叶子节点 - 然后沿着叶子节点链表依次查找直到
age=30 - 比全表扫描效率高得多
🔚 总结:
- ✅ MySQL(InnoDB 引擎)索引底层确实是基于 B+树
- ❌ 不是二叉树,不是哈希表
- ✅ B+树能高效支持范围查询和排序,是关系型数据库中最常用的索引结构
如果你想了解 B+树的图解或示例,我也可以画图给你看。是否需要?
B+ tree的面试题
B+树作为数据库和文件系统中重要的数据结构,相关的题目多涉及 查找、插入、删除、范围查询、页面分裂(Page Split) 等,既有理论分析题,也有实际实现类问题。下面是一些常见且经典的 B+树题目分类,适合用于笔试、面试或深入学习:
🧠 一、基础理解类(适合入门/面试)
这些题主要考察你是否理解 B+树的基本原理:
- B+树与B树的区别?为什么数据库用B+树不用B树?
- 什么是聚簇索引和非聚簇索引?B+树是如何实现的?
- B+树适合的应用场景是什么?为什么适合磁盘存储?
- 一个 B+ 树的阶(fanout)如何影响性能?
- 什么是回表?B+树如何支持“回表查询”?
🧪 二、操作模拟题(适合理解B+树的行为)
这些题通常要求你模拟 B+ 树的操作,比如插入和删除过程,适合画图理解:
- 给定一个空的B+树,按照某个顺序插入一组数字,画出最终的树结构。
- 模拟某个节点插入导致的分裂,描述分裂的过程。
- 从一棵B+树中删除某个键值,说明是否需要合并或重分布?
- 给定一棵B+树,执行范围查找,比如
[10, 50],列出遍历过程。 - 叶子节点的链表结构在实际查找中的作用是什么?请举例。
👨💻 三、实现类编程题(中高级)
如果你对算法实现感兴趣,这些是比较有挑战的题:
- 实现一个支持插入、查找的 B+ 树结构(可以设置阶数)
- 实现 B+ 树范围查询功能:
range(start_key, end_key) - 实现删除操作,并处理节点合并和重分布
- 统计 B+树 的高度、节点个数、叶子个数等属性
- 模拟 Page Split 过程,并输出中间步骤
语言可选:C++ / Java / Python 均可,Python 更容易调试,适合教学。
📚 四、数据库实际场景题(适合MySQL方向)
这些题结合实际 MySQL 应用:
- 为什么 InnoDB 的主键索引必须是唯一的?聚簇索引在 B+ 树中如何体现?
- 为什么建议主键自增?否则会发生什么(比如频繁的中间插入)?
- 为什么不建议用 UUID 作为主键?对 B+ 树有什么影响?
- 多列联合索引在 B+树中是如何构建的?最左前缀原则如何工作?
- Explain 分析中如何判断 B+ 树是否被使用?
🧩 五、综合/趣味题
- 在 B+树 上实现类似 LRU Cache 的功能是否可行?
- 若 B+ 树用于 SSD 存储,是否还需要那么大的阶数?
- 设计一个模拟数据库索引结构的系统,如何使用 B+ 树管理磁盘块?
🛠️ 示例题目(练手)
示例 1:插入模拟
已知一个 B+ 树阶数为
3,向空树中依次插入:5, 10, 15, 20, 25, 30,画出最终树结构。
示例 2:删除模拟
已知一棵 B+ 树包含
5, 10, 15, 20, 25, 30,删除10和15后的结构是怎样的?
示例 3:查找过程
给定如下 B+ 树结构,执行查询
SELECT * WHERE key BETWEEN 25 AND 50,列出遍历过程。

Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.