MySQL索引

3 阅读3分钟

1、MySQL索引本质

1.1 为什么选择B+Tree ?

B+Tree 是多路平衡树,树高度较低,磁盘I/O少,支持高效范围查询。

  1. 较低的树高度:多路特性使得 B+Tree 的高度较低,从而减少查找、插入和删除操作所需的访问节点数量。
  2. 高效的磁盘 I/O:B+Tree 结构能够有效利用磁盘块,减少读取次数,提高数据访问速度。
  3. 支持范围查询:叶子节点通过链表连接,方便进行范围查询和顺序遍历操作。
  4. 平衡性:B+Tree 是自我平衡的,保证了数据的均匀分布,避免了性能下降。
  5. 灵活性:适用于大规模数据存储,能处理动态数据集的频繁更新

1.2 B+Tree特性

  • 多路平衡,树高极低
  • 非叶子节点只存储索引,不存数据
  • 叶子节点形成有序双向链表,支持范围查询
  • 所有数据存储在叶子节点

2、索引类型

2.1 聚簇索引

本质: 数据即索引

特点:

  • 一个表只有一个聚簇索引
  • 主键自动成为聚簇索引
  • 若没有主键,选择第一个unique not null 列
  • 如果都没有,InnoDB创建隐藏的 6 字节 ROWID 作为聚簇索引

优势:

  • 主键查询极快,直接定位数据
  • 范围查询高效:找到起始点后,沿叶子节点链表顺序读取
  • 数据访问局部性好:相邻主键的数据物理上也相邻,减少磁盘寻道

劣势:

  1. 插入速度依赖插入顺序:
  • 按主键顺序插入:速度快,追加写入
  • 随机主键插入:可能触发频繁页分裂
  1. 更新主键代价高昂
  2. 不适合频繁变化的列

2.2 二级索引与回表查询

二级索引的叶子节点不存储实际数据行,而是存储指向主键值的引用。

回表查询: 使用二级索引查找数据时,需要通过主键值回到主表中进行查询,这个过程称为回表查询。

实际步骤: 索引扫描 -> 回表查询 -> 合并结果

避免回表优化:覆盖索引

覆盖索引,包含查询所需要的所有列,在查询时可以直接从索引中获取数据,而不需要访问实际的表数据。

3、索引设计法则

  1. 只为搜索、排序、分组的列创建索引
  2. 考虑索引选择性:选择性 = 不重复值数量 / 总行数,选择性越高效果越好
  3. 短索引原则:使用前缀索引减少索引大小,但会降低选择性,需权衡
  4. 避免过多索引:每个索引增加写操作成本
  5. 建议:读多写少表可多索引,写多读少表应精简索引

4、EXPLAIN 命令

EXPLAIN命令:分析SQL查询的执行计划

输出字段重点解读

  • type: 访问类型,从好到差:system > const > eq_ref > ref > range > index > ALL
  • ref: 非唯一索引查找;ALL: 全表扫描(最差)
  • possible_keys: 可能用到的索引
  • key: 实际使用的索引
  • rows: 预计扫描行数
  • Extra: 额外信息(Using index:覆盖索引;Using where:需要回表)