1、MySQL索引本质
1.1 为什么选择B+Tree ?
B+Tree 是多路平衡树,树高度较低,磁盘I/O少,支持高效范围查询。
- 较低的树高度:多路特性使得 B+Tree 的高度较低,从而减少查找、插入和删除操作所需的访问节点数量。
- 高效的磁盘 I/O:B+Tree 结构能够有效利用磁盘块,减少读取次数,提高数据访问速度。
- 支持范围查询:叶子节点通过链表连接,方便进行范围查询和顺序遍历操作。
- 平衡性:B+Tree 是自我平衡的,保证了数据的均匀分布,避免了性能下降。
- 灵活性:适用于大规模数据存储,能处理动态数据集的频繁更新
1.2 B+Tree特性
- 多路平衡,树高极低
- 非叶子节点只存储索引,不存数据
- 叶子节点形成有序双向链表,支持范围查询
- 所有数据存储在叶子节点
2、索引类型
2.1 聚簇索引
本质: 数据即索引
特点:
- 一个表只有一个聚簇索引
- 主键自动成为聚簇索引
- 若没有主键,选择第一个unique not null 列
- 如果都没有,InnoDB创建隐藏的 6 字节 ROWID 作为聚簇索引
优势:
- 主键查询极快,直接定位数据
- 范围查询高效:找到起始点后,沿叶子节点链表顺序读取
- 数据访问局部性好:相邻主键的数据物理上也相邻,减少磁盘寻道
劣势:
- 插入速度依赖插入顺序:
- 按主键顺序插入:速度快,追加写入
- 随机主键插入:可能触发频繁页分裂
- 更新主键代价高昂
- 不适合频繁变化的列
2.2 二级索引与回表查询
二级索引的叶子节点不存储实际数据行,而是存储指向主键值的引用。
回表查询: 使用二级索引查找数据时,需要通过主键值回到主表中进行查询,这个过程称为回表查询。
实际步骤: 索引扫描 -> 回表查询 -> 合并结果
避免回表优化:覆盖索引
覆盖索引,包含查询所需要的所有列,在查询时可以直接从索引中获取数据,而不需要访问实际的表数据。
3、索引设计法则
- 只为搜索、排序、分组的列创建索引
- 考虑索引选择性:选择性 = 不重复值数量 / 总行数,选择性越高效果越好
- 短索引原则:使用前缀索引减少索引大小,但会降低选择性,需权衡
- 避免过多索引:每个索引增加写操作成本
- 建议:读多写少表可多索引,写多读少表应精简索引
4、EXPLAIN 命令
EXPLAIN命令:分析SQL查询的执行计划
输出字段重点解读:
- type: 访问类型,从好到差:system > const > eq_ref > ref > range > index > ALL
- ref: 非唯一索引查找;ALL: 全表扫描(最差)
- possible_keys: 可能用到的索引
- key: 实际使用的索引
- rows: 预计扫描行数
- Extra: 额外信息(Using index:覆盖索引;Using where:需要回表)