为什么在MySQL集群中不建议使用UUID作为聚簇索引主键

轻明君_1367

轻明君_1367

2026-09-23

244人浏览

原创

mysql不建议用uuid做聚簇索引主键,根本原因是innodb要求主键有序插入以避免页分裂,而v4 uuid完全随机,导致新记录大概率插入数据页中间,页满即触发确定性页分裂,引发i/o激增、碎片增长和缓存命中率下降。

为什么在mysql集群中不建议使用uuid作为聚簇索引主键

MySQL集群中不建议用UUID做聚簇索引主键,根本原因不是“分布式”本身,而是InnoDB的聚簇索引机制与UUID的随机性之间存在不可调和的冲突——每次插入都大概率触发页分裂,写入性能断崖式下跌,且无法靠加机器或分库分表掩盖。

为什么UUID插入必然引发高频页分裂

InnoDB聚簇索引要求数据物理存储顺序 = 主键值排序顺序。UUID()生成的是v4随机字节序列(如550e8400-e29b-41d4-a716-446655440000),其二进制比较无时间局部性。新记录插入时需二分查找位置,结果90%以上落在已有数据页中间而非末尾。一旦目标页已满(默认填充率约15/16KB),InnoDB必须执行页分裂:搬走约一半记录、分配新页、更新父节点指针、写doublewrite buffer。

  • 这不是偶发抖动,是确定性开销:实测每插入1000行UUID,平均触发1.7次页分裂
  • SHOW ENGINE INNODB STATUS里频繁出现Pages split due to insert
  • SHOW TABLE STATUSData_free持续增长,常达实际数据体积的30%以上
  • 分裂后原页利用率暴跌至50%以下,形成不可逆的索引碎片

BINARY(16)或UUID_TO_BIN()并不能解决问题

CHAR(36)改成BINARY(16)只省了20字节存储,但没动“随机性”这个命门。InnoDB比较BINARY值仍是逐字节比对,而标准UUID前4字节(时间低位)并不单调递增,插入位置依然不可预测。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • UUID_TO_BIN(uuid, 0)(即不带swap_flag)只是压缩编码,字节序未重排,仍是随机序
  • 必须用UUID_TO_BIN(uuid, 1)才将时间戳高位左移,实现近似有序;但仅限MySQL 8.0+
  • 即使用了UUID_TO_BIN(uuid, 1),同一毫秒内生成的多个UUID后缀仍随机,高并发写入下仍会集中撑满单页
  • 若字段类型仍是CHAR(36),转换白做——BIN_TO_UUID()查出来的还是乱序字符串

自增ID在集群中真就不可用?

很多人误以为“集群=必须UUID”,其实错把ID生成逻辑和主键设计混为一谈。自增ID的缺陷是单点生成,但解决方案成熟:

  • 各实例配置不同auto_increment_offsetauto_increment_increment,例如5台DB设offset为1/2/3/4/5、increment=5,天然避免冲突
  • Proxy层(如Vitess、ShardingSphere)统一分发ID,后端仍用自增,兼顾性能与全局唯一
  • 业务层用雪花ID生成BIGINT,存入BIGINT UNSIGNED字段——注意校准时钟回拨,worker_id必须全局唯一
  • 完全回避主键唯一性问题:用CREATE TABLE ... (id BIGINT PRIMARY KEY, logical_id VARCHAR(36)),UUID存为普通字段,主键保持自增

ORDER BY id和范围查询会彻底失效

当主键是UUID时,SELECT * FROM t ORDER BY id LIMIT 10几乎必然退化为全表扫描。因为B+树叶子节点物理顺序与主键逻辑顺序严重脱钩,InnoDB无法利用双向链表跳跃遍历,必须逐页检查所有叶子节点才能凑够10条最小值。

  • 自增ID下该查询通常只需读1–2个连续页;UUID下可能扫几十甚至上百页
  • 二级索引叶子节点存的是主键值,BINARY(16)让单页索引项减少约45%,树高增加,JOIN和多条件查询I/O成本翻倍
  • Buffer Pool缓存的页彼此离散,范围查询无法触发操作系统预读,随机I/O增加3–5倍
  • 监控上表现为innodb_buffer_pool_reads飙升、磁盘IO使用率长期>90%

真正难处理的不是“怎么换主键”,而是现有UUID主键表的数据迁移路径——页分裂造成的碎片不会因换主键自动修复,OPTIMIZE TABLEALTER TABLE ... FORCE会锁表,且重建索引时若仍用UUID,碎片照旧。线上系统改主键前,务必先压测页分裂率和Buffer Pool污染程度。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql uuid主键 mysql索引

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

1933

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1179

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

695

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2512

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

4128

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

979

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

4391

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

3982

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

5114

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 170人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 274人学习