Boot+Cloud项目学习:macrozheng.com
在 MySQL 中,使用 UUID 作为主键 在大表中可能会导致性能问题,尤其是在插入和修改数据时效率较低。以下是详细的原因分析,以及为什么修改数据会导致索引刷新,以及字符主键为什么效率较低。
1. UUID 作为主键的问题
(1)UUID 的特性
-
UUID 是一个 128 位的字符串,通常表示为 36 个字符(例如: 550e8400-e29b-41d4-a716-446655440000)。 -
UUID 是全局唯一的,适合分布式系统中生成唯一标识。
(2)UUID 作为主键的缺点
1. 索引效率低
-
索引大小:UUID 是字符串类型,占用空间较大(36 字节),而整型主键(如 BIGINT)仅占用 8 字节。索引越大,存储和查询的效率越低。 -
索引分裂:UUID 是无序的,插入新数据时,可能会导致索引树频繁分裂和重新平衡,影响性能。
2. 插入性能差
-
随机性:UUID 是无序的,每次插入新数据时,新记录可能会插入到索引树的任意位置,导致索引树频繁调整。 -
页分裂:InnoDB 存储引擎使用 B+ 树作为索引结构,随机插入会导致页分裂,增加磁盘 I/O 操作。
3. 查询性能差
-
比较效率低:字符串比较比整型比较慢,尤其是在大表中,查询性能会显著下降。 -
索引扫描范围大:UUID 索引占用的空间大,导致索引扫描的范围更大,查询效率降低。
2. 修改数据导致索引刷新的原因
(1)索引的作用
-
索引是为了加速查询而创建的数据结构(如 B+ 树)。 -
当数据被修改时,索引也需要同步更新,以保持数据的一致性。
(2)修改数据对索引的影响
-
更新主键: -
如果修改了主键值,MySQL 需要删除旧的主键索引记录,并插入新的主键索引记录。 -
这个过程会导致索引树的调整,增加磁盘 I/O 操作。 -
更新非主键列: -
如果修改的列是索引列(如唯一索引、普通索引),MySQL 需要更新对应的索引记录。 -
这个过程也会导致索引树的调整。
(3)UUID 主键的额外开销
-
由于 UUID 是无序的,修改主键值时,新值可能会插入到索引树的不同位置,导致索引树频繁调整。 -
相比于有序的主键(如自增 ID),UUID 主键的修改操作代价更高。
3. 字符主键导致效率降低的原因
(1)存储空间大
-
字符主键(如 UUID)占用的存储空间比整型主键大。 -
索引的大小直接影响查询性能,索引越大,查询时需要的磁盘 I/O 操作越多。
(2)比较效率低
-
字符串比较比整型比较慢,尤其是在大表中,查询性能会显著下降。 -
例如, WHERE id = '550e8400-e29b-41d4-a716-446655440000'的效率低于WHERE id = 12345。
(3)索引分裂
-
字符主键通常是无序的,插入新数据时,可能会导致索引树频繁分裂和重新平衡,影响性能。
4. 如何优化 UUID 主键的性能
(1)使用有序 UUID
-
使用有序 UUID(如 UUIDv7),减少索引分裂和页分裂。 -
有序 UUID 的生成方式可以基于时间戳,保证插入顺序。
(2)将 UUID 存储为二进制
-
将 UUID 存储为
BINARY(16)而不是CHAR(36),减少存储空间。CREATE TABLE users (
id BINARY(16) PRIMARY KEY,
name VARCHAR(255)
);
(3)使用自增主键 + UUID
-
使用自增主键作为物理主键,UUID 作为逻辑主键。
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
uuid CHAR(36) UNIQUE,
name VARCHAR(255)
);
(4)分区表
-
对大表进行分区,减少单个索引树的大小,提高查询性能。
总结
-
UUID 作为主键的缺点: -
索引效率低,插入和查询性能差。 -
修改数据时,索引需要频繁刷新,导致性能下降。 -
字符主键效率低的原因: -
存储空间大,比较效率低,索引分裂频繁。 -
优化建议: -
使用有序 UUID 或二进制存储。 -
结合自增主键和 UUID。 -
对大表进行分区。
作者:码农liuxin
来源:juejin.cn/post/7478495083374559270
Github上标星11K的微服务实战项目mall-swarm,全套 视频教程 来了!全套教程约26小时,共59期,如果你想学习目前最新的微服务技术栈,同时提高自己微服务项目的开发能力的话,不妨了解下,下面是项目的整体架构图,感兴趣的小伙伴可以点击链接 mall-swarm视频教程 加入学习。
整套 视频教程 的内容还是非常完善的,涵盖Spring Cloud核心组件、微服务项目实战、Kubernetes容器化部署等内容,你也可以点击链接 mall-swarm视频教程 了解更多内容。

