📚 目录
- 什么是索引?
- 索引的分类
- B+树结构详解
- MySQL 为什么使用 B+树而不是 B 树?
- 聚簇索引 vs 非聚簇索引
- 覆盖索引、最左前缀原则
- 索引失效的常见原因
- 索引优化建议
- 图解演示 B+树查找过程
1. ✅ 什么是索引?
索引是用于加速数据查询的数据结构,类似于书籍的目录。它能在大量数据中快速定位所需的记录,显著提高 SELECT
查询效率。
通俗比喻:
- 没有索引:全表扫描,就像翻书每一页找人名;
- 有索引:看目录直接跳页,定位迅速。
2. 📂 索引的分类(MySQL InnoDB)
索引类型 | 说明 |
---|---|
主键索引 | 聚簇索引,按主键排序存储数据 |
普通索引 | 非唯一索引,可以有重复值 |
唯一索引 | 索引列必须唯一,允许 NULL |
组合索引 | 多列联合创建的索引,遵循最左前缀原则 |
覆盖索引 | 查询字段只在索引中即可完成,无需回表 |
全文索引 | 对文本字段进行全文匹配搜索(MyISAM 支持) |
3. 🌳 B+树结构详解
MySQL(InnoDB)使用 B+树(BPlus Tree) 作为默认索引结构。
🧱 结构特性
- 所有数据都存储在叶子节点;
- 叶子节点之间通过双向链表连接,便于范围查找;
- 非叶子节点仅存储键值和指向子节点的指针;
- 每个节点可以存储多个键,减少树的高度;
🧠 时间复杂度
查找效率为 O(logm N),其中 m
为节点的分支因子(高扇出性带来低高度)。
🖼️ B+树结构图(示意)
[10 | 20 | 30]
/ | \
... ... ...
[5,7,9] [12,18] [21,27,29] <- 叶子节点存储数据
- 所有的 key 都出现在叶子节点;
- 中间节点只用于索引定位;
- 叶子节点顺序排列,便于区间扫描。
4. ❓ 为什么使用 B+树而不是 B 树?
特性 | B 树 | B+ 树(MySQL 使用) |
---|---|---|
数据存储位置 | 所有节点都存储数据 | 只在叶子节点存储数据 |
查找效率 | 所有节点都有数据,路径不统一 | 路径统一,便于磁盘页缓存命中 |
范围查询 | 不方便 | 叶子节点链表连接,范围查询优秀 |
I/O 访问次数 | 多 | 少,适合磁盘块预读 |
实际使用情况 | 较少 | MySQL InnoDB、Oracle 使用 |
5. 🧩 聚簇索引 vs 非聚簇索引
✅ 聚簇索引(Clustered Index)
- 主键索引,叶子节点存储整行数据;
- 表数据与索引结构合并在一起;
- 一个表只能有一个聚簇索引(主键或唯一非空索引);
🔁 非聚簇索引(Secondary Index)
- 叶子节点存储主键值而非完整行;
- 查询时需通过回表操作找到真正数据行;
- 可有多个非聚簇索引。
6. 📌 覆盖索引、最左前缀原则
覆盖索引(Covering Index)
如果一个查询中所需的字段都能从索引中获取,就不会回表,大大提高查询效率。
-- 假设已建立索引 idx_name_age(name, age)
SELECT name FROM user WHERE name = 'Tom'; -- 覆盖索引
最左前缀原则(重要)
组合索引只能命中最左连续字段:
INDEX(name, age, gender)
WHERE name = ? -- 命中 ✅
WHERE name = ? AND age = ? -- 命中 ✅
WHERE age = ? -- 不命中 ❌
WHERE name LIKE 'T%' -- 命中 ✅
WHERE name LIKE '%T' -- 不命中 ❌
7. ⚠️ 索引失效的常见原因
情况 | 是否索引生效 |
---|---|
OR 查询中部分列无索引 | ❌ |
索引列参与函数/表达式 | ❌ |
% 通配符在前的模糊匹配 | ❌ |
隐式类型转换(int = ‘123abc’) | ❌ |
使用 != 或 <> | ❌ |
使用 IS NULL / IS NOT NULL | ✅/❌ 视情况 |
8. 📈 索引优化建议
- 优先使用 高区分度列建索引(选择性高);
- 使用覆盖索引避免回表;
- 多条件查询时遵循最左前缀原则;
- 避免对索引列使用函数、表达式、类型不一致等;
- 控制组合索引的列数,避免冗余;
- 利用
EXPLAIN
分析 SQL 是否使用索引。
9. 🔍 图解查找过程(以 name 索引查找为例)
查询 name = 'Tom'
↓
B+树根节点
↓二分查找找到区间
↓顺着指针进入下一层子节点
↓直到叶子节点
→ 精确匹配 name = 'Tom'
→ 读取整行(聚簇)或回表读取(非聚簇)
📘 推荐阅读与工具
- 📚《高性能MySQL》第三版(第4章 索引优化)
- 🔍 使用
EXPLAIN
/SHOW INDEX
分析索引命中情况 - 🔨 数据结构可视化工具:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html
如你需要我继续写一篇关于:
- 🔁 Hash索引 VS B+树索引性能比较;
- ✅ 多字段联合索引的设计实践;
- 📊 EXPLAIN 分析 SQL 查询优化;
欢迎继续告诉我,我可以继续生成详细内容。
发表回复