linux学习笔记(38)mysql索引详解
·
索引详解
索引是什么
索引是一种特殊的文件,它包含着对数据表里所有记录的引用指针。简单讲,就像一本书前面的目录,能加快查询速度。
- 索引是帮助mysql高效获取数据的数据结构
- 索引存储在文件系统中
- 索引的文件存储形式与存储引擎有关
- 索引文件的结构
索引为什么选择b+树
可以考虑作为索引的数据结构有如下几种,下面介绍下不同数据结构的特点:
- hash表
- 二叉树
- b树
- b+树
1. 为什么不选 Hash 表
- 不支持范围查询Hash 是等值匹配(=),没法做
> < >= <= between、排序、分页、前缀模糊查询。 - 哈希冲突冲突会退化成链表,查询性能退化。
- 不支持有序遍历索引排序、联合索引最左匹配、order by 完全不友好。
- 磁盘存储不友好Hash 桶离散,无法按页 / 块批量预读,缓存利用率低。
适用:仅等值查询场景(如 InnoDB 自适应哈希索引),不能做主索引结构。
2. 为什么不选 普通二叉树 / 二叉搜索树 BST
- 树高不可控,容易退化成链表数据有序插入时,BST 直接变成单链表,时间复杂度退化成 O (n)。
- 层高太高千万级数据,二叉树层高几十层,磁盘要几十次 IO,慢到爆炸。
- 节点度只有 2,每页存的数据太少磁盘一次读一页,二叉树一个页块存不了几个关键字,IO 次数暴增。
3. 为什么不选 红黑树
红黑树是平衡二叉树,解决了 BST 倾斜问题,但仍有硬伤:
- 还是二叉,分支太少每个节点最多 2 个子节点,树高依然很高,大数据量磁盘 IO 次数多。
- 不适合磁盘块存储红黑树节点小、碎片化,没法利用磁盘预读、页批量加载特性。
- 范围查询效率低范围查询要中序遍历,没法像 B + 树一样叶子节点链表直接顺序扫。
- 维护成本高插入删除旋转调整多,数据库海量数据下开销大。
红黑树适合内存结构,不适合磁盘索引。
4. 为什么不选 B 树(多路平衡查找树)
B 树已经是多路平衡树、矮胖结构,比二叉树强很多,但对比 B + 树仍有短板:
-
非叶子节点也存数据 + 行记录 B 树:所有节点都存关键字 + 数据 B + 树:只有叶子节点存完整数据,非叶子只存索引键→ B 树非叶子节点占用空间大,每页能存的索引个数变少,树高变高,IO 变多。
-
范围查询麻烦B 树范围查询需要中序遍历整棵树,来回跳节点、跳磁盘块。B + 树叶子节点是双向链表,范围查询直接链表顺序遍历,不用回溯非叶子节点。
-
磁盘预读利用率低B 树数据分散在各层节点,无法批量顺序读取;B + 树所有数据都在叶子,天然有序、连续、适合批量分页 / 范围扫描。
二、B + 树 凭什么胜出?(核心优势)
-
多路矮胖,树高极低一个节点可以存成百上千个索引,千万级数据也就3~4 层,一次查询仅 3~4 次磁盘 IO。
-
非叶子只存索引键,不存数据每页能放更多索引,进一步压低树高,IO 次数最少。
-
叶子节点双向链表有序完美支持:范围查询、排序、分页、全表扫描、前缀匹配。
-
磁盘预读特性拉满数据全在叶子节点集中存放,符合磁盘局部性原理、顺序预读,缓存命中率极高。
-
插入删除稳定平衡多路平衡,分裂合并规则简单,维护开销可控,适合高并发数据库。
三、一句话总结对比
| 结构 | 致命缺点 | 适用场景 |
|---|---|---|
| Hash 表 | 不支持范围、排序、有序遍历 | 仅等值查询 |
| 普通二叉树 | 易倾斜成链表、层高太高 | 无实际索引使用 |
| 红黑树 | 二叉分支、层高仍高、不适合磁盘批量读 | 内存有序容器 |
| B 树 | 非叶子存数据、每页索引少、范围查询差 | 文件系统小索引 |
| B + 树 | 几乎无短板 | 数据库磁盘索引标配 |
四、面试极简背诵版
- Hash:只能等值,不支持范围排序;
- 二叉树:易倾斜、层高太高、IO 爆炸;
- 红黑树:还是二叉,层高高,不适合磁盘批量预读,范围查询弱;
- B 树:非叶子存数据,每页索引少、树高更高,范围查询不如 B + 树链表遍历;
- B + 树:矮胖多路、非叶子只存索引、叶子链表有序、适配磁盘 IO 和范围分页,完美适配数据库索引。
1. 索引的创建和使用
-- 创建普通索引
CREATE INDEX idx_student_name ON students(name);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_student_email ON students(email);
-- 创建复合索引
CREATE INDEX idx_student_class_score ON students(class_id, score);
-- 查看索引
SHOW INDEX FROM students;
-- 删除索引
DROP INDEX idx_student_name ON students;
2. 索引性能测试
-- 开启性能分析
SET PROFILING = 1;
-- 无索引查询
SELECT * FROM students WHERE name = '张三';
-- 创建索引后查询
CREATE INDEX idx_name ON students(name);
SELECT * FROM students WHERE name = '张三';
-- 查看查询时间
SHOW PROFILES;
索引的核心思想:
- 索引像书的目录 - 快速定位,避免全表扫描
- B+树结构 - 多层查找,效率极高
- 用EXPLAIN分析 - 查看索引是否生效
- 复合索引注意顺序 - (A,B)索引能查A,不能只查B
- 索引有代价 - 占用空间,降低写性能
黄金法则:只为经常查询、数据区分度高的字段创建索引!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)