Mysql:索引与B+树

在日常MySQL建表中,我们有三种定义主键的方式。不同的主键定义方式,在InnoDB底层B+树聚簇索引的创建时机、磁盘开销、底层逻辑完全不同。

方式一:字段后直接定义主键(内联主键)

sql 复制代码
CREATE TABLE user(
    id INT PRIMARY KEY,
    name VARCHAR(20)
);
 
  1. 建表语句执行的同时,InnoDB直接以当前主键字段构建聚簇索引B+树

  2. 数据在磁盘物理页中有序连续存储

  3. 后续新增数据直接按照B+树规则插入,不会产生任何表重构。

  4. 性能最优,是开发中最推荐的方式。

总结

建表 + 聚簇B+树 一次性生成,零额外开销。

方式二:先建表,后续再追加主键

sql 复制代码
CREATE TABLE user(
    id INT,
    name VARCHAR(20)
);


ALTER TABLE user ADD PRIMARY KEY(id);
  1. InnoDB表必须要有聚簇索引。建表无显式主键时,InnoDB按照优先级自动生成临时的聚簇B+树。

无主键时优先级:
自定义主键 > 唯一索引 > 隐藏6字节 row_id

  1. 执行 alter 新增主键时:

销毁原本的临时B+树,全表数据重新磁盘排序, 基于新的自定义主键,重新完整构建一颗全新的聚簇B+树

  1. 整个过程会产生大量IO开销,表数据量越大,性能损耗越严重。

4**.删除主键也会触发全表重构。**

总结

数据量大时会产生大量磁盘IO、锁表、性能雪崩,生产环境严禁后期添加主键。

方式三:定义主键 + 额外普通索引/联合索引

sql 复制代码
CREATE TABLE user(
    id INT PRIMARY KEY,
    name VARCHAR(20),
    INDEX idx_name(name)
);

InnoDB会同时存在两颗及以上B+树:

  1. 聚簇索引B+树

叶子节点存储完整的整行数据,以主键为排序规则

  1. 二级索引(普通索引)B+树

叶子节点只存储索引列的值 + 对应的主键值 ,不存储整行数据。

  1. 回表机制

当通过二级索引查询数据时:
先在二级B+树找到对应主键 → 再拿着主键去聚簇B+树中查询完整数据,这个过程叫做回表查询。

复合索引可以不回表,已知 a 找 b ,在(a,b)二级B+树能直接找到 b

索引创建原则

  1. 比较频繁作为查询条件的字段应该创建索引

  2. 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件

3.更新非常频繁的字段不适合作创建索引

  1. 不会出现在where子句中的字段不该创建索引
相关推荐
Java成神之路-1 小时前
MySQL 函数索引与虚拟列深度解析
mysql
Languorous.1 小时前
Linux 系统安装 MySQL(CentOS8/Ubuntu),命令行实操完整版
linux·mysql·ubuntu
huaiixinsi1 小时前
Canal + Outbox、Kafka 选型与高可用、Caffeine 底层原理总结
java·数据库·分布式·mysql·spring·adb·kafka
代码中介商1 小时前
MySQL 核心进阶:事务、隔离级别与视图实战
数据库·mysql
思麟呀2 小时前
MySQL复合查询与内外连接
android·数据库·mysql
Mahir0810 小时前
Redis 与 MySQL 数据同步:一致性保证的完整解决方案
数据库·redis·mysql·缓存·面试·数据一致性
·醉挽清风·11 小时前
学习笔记—MySQL—库表操作
笔记·学习·mysql
数据库小学妹13 小时前
数据库连接池避坑指南:告别“连接超时”与“资源耗尽”,让系统跑得更快!
数据库·redis·sql·mysql·缓存·dba
前进的李工13 小时前
EXPLAIN输出格式全解析:JSON、TREE与可视化
开发语言·数据库·mysql·性能优化·explain