推荐使用整型主键而非uuid,因整型比较快、存储省,可降低b+树深度、减少页分裂和二级索引膨胀;uuid随机插入导致频繁页分裂、io增加、缓存命中率下降。

MySQL推荐用整型(如 INT 或 BIGINT)而非字符串(如 VARCHAR(36) 存 UUID)作主键,核心原因就两条:索引比较快、存储更省,且这两点直接决定 B+ 树的深度、页分裂频率和二级索引膨胀程度。
整型比较比字符串快一个数量级
MySQL 在 B+ 树非叶子节点做范围或等值查找时,本质是大量主键值之间的比较操作。整型比较是 CPU 原生支持的单指令操作(比如一次比较 8 字节 BIGINT),而字符串比较必须逐字符查 ASCII 码,遇到前缀相同时还得继续往后比——UUID 这种 32 位十六进制字符串平均要比较十几甚至几十个字节才能分出大小。
实测中,同等数据量下 WHERE id = 123456 的响应通常比 WHERE uuid = 'a1b2c3...' 快 5–30 倍,尤其在高并发点查或范围扫描时差距更明显。
字符串主键让所有二级索引“变胖”
InnoDB 的二级索引叶子节点不存行数据,只存主键值。如果主键是 BIGINT(8 字节),那每个二级索引条目就只多占 8 字节;但如果主键是 UTF8MB4 编码的 UUID(36 字符 ≈ 108 字节),那每个二级索引条目就要多存约 108 字节。
这意味着:
- 同样大小的页(默认 16KB)能装的索引项更少 → B+ 树层级更深 → 查询需更多磁盘 IO
- 每加一个二级索引,表总空间增长幅度远超整型主键场景
- 内存中 Buffer Pool 能缓存的有效索引页数下降,缓存命中率降低
自增整型能避免页分裂和随机写入
UUID 是随机生成的,插入时新记录可能落在 B+ 树任意叶子页中间,导致频繁页分裂(page split):原页拆成两页,部分数据搬移,还可能触发上层节点分裂。这不仅是写放大,还会造成碎片化和锁竞争。
而 AUTO_INCREMENT 整型主键天然递增,新记录总追加到最右叶子页末尾。只要该页有空余空间,就是顺序写入;即使触发页分裂,也只影响最右侧路径,对整体树结构扰动最小。
注意:innodb_autoinc_lock_mode 设置不当(如 0)会在高并发插入时引发 AUTO_INC 锁争用,但这是可调优的问题,不是整型本身的缺陷。
真正容易被忽略的是:哪怕你坚持用 UUID,也别直接当主键;更稳妥的做法是保留 BIGINT 自增主键,再额外加一列 uuid 并建唯一索引——既满足业务侧对“全局唯一标识”的需求,又不牺牲 InnoDB 底层性能。主键选型从来不是“好不好看”,而是“B+ 树疼不疼”。











