dbaplus社群 2024年08月28日
别乱用UUID了,自增ID和UUID性能差距你测过吗?
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章对自增ID和UUID作为主键在不同规模场景下的性能进行了测试和分析

🎈自增ID在节省磁盘空间方面表现出色,比UUID小一半左右。在范围like查询、写入测试、备份和恢复等方面,自增ID性能优于UUID

💡在500W和1000W记录表的测试中,普通单条或少量记录检索时,自增ID和UUID在效率上相差不大,但范围查询及统计汇总时,自增ID效率更高

🌟自增ID主键加步长适合中等规模分布式场景,实现简单,后期维护简单,但首次设置较复杂。UUID适合小规模分布式环境,搭建简单,但存在诸多缺点

唐宋缘明卿_cris 2024-08-27 07:15 广东

不同的规模,选择可能截然相反……


准备表&数据


UC_USER,自增ID为主键,表结构类似如下:


CREATE TABLE `UC_USER` (  `ID` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',  `USER_NAME` varchar(100) DEFAULT NULL COMMENT '用户名',  `USER_PWD` varchar(200) DEFAULT NULL COMMENT '密码',  `BIRTHDAY` datetime DEFAULT NULL COMMENT '生日',  `NAME` varchar(200) DEFAULT NULL COMMENT '姓名',  `USER_ICON` varchar(500) DEFAULT NULL COMMENT '头像图片',  `SEX` char(1) DEFAULT NULL COMMENT '性别, 1:男,2:女,3:保密',  `NICKNAME` varchar(200) DEFAULT NULL COMMENT '昵称',  `STAT` varchar(10) DEFAULT NULL COMMENT '用户状态,01:正常,02:冻结',  `USER_MALL` bigint(20) DEFAULT NULL COMMENT '当前所属MALL',  `LAST_LOGIN_DATE` datetime DEFAULT NULL COMMENT '最后登录时间',  `LAST_LOGIN_IP` varchar(100) DEFAULT NULL COMMENT '最后登录IP',  `SRC_OPEN_USER_ID` bigint(20) DEFAULT NULL COMMENT '来源的联合登录',  `EMAIL` varchar(200) DEFAULT NULL COMMENT '邮箱',  `MOBILE` varchar(50) DEFAULT NULL COMMENT '手机',  `IS_DEL` char(1) DEFAULT '0' COMMENT '是否删除',  `IS_EMAIL_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定邮箱',  `IS_PHONE_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定手机',  `CREATER` bigint(20) DEFAULT NULL COMMENT '创建人',  `CREATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',  `UPDATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改日期',  `PWD_INTENSITY` char(1) DEFAULT NULL COMMENT '密码强度',  `MOBILE_TGC` char(64) DEFAULT NULL COMMENT '手机登录标识',  `MAC` char(64) DEFAULT NULL COMMENT 'mac地址',  `SOURCE` char(1) DEFAULT '0' COMMENT '1:WEB,2:IOS,3:ANDROID,4:WIFI,5:管理系统, 0:未知',  `ACTIVATE` char(1) DEFAULT '1' COMMENT '激活,1:激活,0:未激活',  `ACTIVATE_TYPE` char(1) DEFAULT '0' COMMENT '激活类型,0:自动,1:手动',  PRIMARY KEY (`ID`),  UNIQUE KEY `USER_NAME` (`USER_NAME`),  KEY `MOBILE` (`MOBILE`),  KEY `IDX_MOBILE_TGC` (`MOBILE_TGC`,`ID`),  KEY `IDX_EMAIL` (`EMAIL`,`ID`),  KEY `IDX_CREATE_DATE` (`CREATE_DATE`,`ID`),  KEY `IDX_UPDATE_DATE` (`UPDATE_DATE`)) ENGINE=InnoDB AUTO_INCREMENT=7122681 DEFAULT CHARSET=utf8 COMMENT='用户表'

UC_USER_PK_VARCHAR表,字符串ID为主键,采用uuid:


CREATE TABLE `UC_USER_PK_VARCHAR_1` (  `ID` varchar(36) CHARACTER SET utf8mb4 NOT NULL DEFAULT '0' COMMENT '主键',  `USER_NAME` varchar(100) DEFAULT NULL COMMENT '用户名',  `USER_PWD` varchar(200) DEFAULT NULL COMMENT '密码',  `BIRTHDAY` datetime DEFAULT NULL COMMENT '生日',  `NAME` varchar(200) DEFAULT NULL COMMENT '姓名',  `USER_ICON` varchar(500) DEFAULT NULL COMMENT '头像图片',  `SEX` char(1) DEFAULT NULL COMMENT '性别, 1:男,2:女,3:保密',  `NICKNAME` varchar(200) DEFAULT NULL COMMENT '昵称',  `STAT` varchar(10) DEFAULT NULL COMMENT '用户状态,01:正常,02:冻结',  `USER_MALL` bigint(20) DEFAULT NULL COMMENT '当前所属MALL',  `LAST_LOGIN_DATE` datetime DEFAULT NULL COMMENT '最后登录时间',  `LAST_LOGIN_IP` varchar(100) DEFAULT NULL COMMENT '最后登录IP',  `SRC_OPEN_USER_ID` bigint(20) DEFAULT NULL COMMENT '来源的联合登录',  `EMAIL` varchar(200) DEFAULT NULL COMMENT '邮箱',  `MOBILE` varchar(50) DEFAULT NULL COMMENT '手机',  `IS_DEL` char(1) DEFAULT '0' COMMENT '是否删除',  `IS_EMAIL_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定邮箱',  `IS_PHONE_CONFIRMED` char(1) DEFAULT '0' COMMENT '是否绑定手机',  `CREATER` bigint(20) DEFAULT NULL COMMENT '创建人',  `CREATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',  `UPDATE_DATE` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改日期',  `PWD_INTENSITY` char(1) DEFAULT NULL COMMENT '密码强度',  `MOBILE_TGC` char(64) DEFAULT NULL COMMENT '手机登录标识',  `MAC` char(64) DEFAULT NULL COMMENT 'mac地址',  `SOURCE` char(1) DEFAULT '0' COMMENT '1:WEB,2:IOS,3:ANDROID,4:WIFI,5:管理系统, 0:未知',  `ACTIVATE` char(1) DEFAULT '1' COMMENT '激活,1:激活,0:未激活',  `ACTIVATE_TYPE` char(1) DEFAULT '0' COMMENT '激活类型,0:自动,1:手动',  PRIMARY KEY (`ID`),  UNIQUE KEY `USER_NAME` (`USER_NAME`),  KEY `MOBILE` (`MOBILE`),  KEY `IDX_MOBILE_TGC` (`MOBILE_TGC`,`ID`),  KEY `IDX_EMAIL` (`EMAIL`,`ID`),  KEY `IDX_CREATE_DATE` (`CREATE_DATE`,`ID`),  KEY `IDX_UPDATE_DATE` (`UPDATE_DATE`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

500w级数据测试


# 自增id为主键的表
mysql> select count(1) from UC_USER;
+----------+
| count(1) |
+----------+
| 5720112 |
+----------+
1 row in set (0.00 sec)


# uuid为主键的表
mysql> select count(1) from UC_USER_PK_VARCHAR_1;
+----------+
| count(1) |
+----------+
| 5720112 |
+----------+
1 row in set (1.91 sec)

1、录入500W数据,自增ID节省一半磁盘空间


占据的空间容量来看,自增ID比UUID小一半左右。



2、单个数据走索引查询,自增id和uuid相差不大



3、范围like查询,自增ID性能优于UUID



4、写入测试,自增ID是UUID的4倍



5、备份和恢复,自增ID性能优于UUID



500W总结


在500W记录表的测试下:


1、普通单条或者20条左右的记录检索,uuid为主键的相差不大几乎效率相同;

2、 但是范围查询特别是上百成千条的记录查询,自增id的效率要大于uuid;

3、在范围查询做统计汇总的时候,自增id的效率要大于uuid;

4、在存储上面,自增id所占的存储空间是uuid的1/2;

5、在备份恢复上,自增ID主键稍微优于UUID。


1000W总结


在1000W记录表的测试下:


1、普通单条或者20条左右的记录检索,自增主键效率是uuid主键的2到3倍;

2、但是范围查询特别是上百成千条的记录查询,自增id的效率要大于uuid;

3、在范围查询做统计汇总的时候,自增id主键的效率是uuid主键1.5到2倍;

4、在存储上面,自增id所占的存储空间是uuid的1/2;

5、在写入上面,自增ID主键的效率是UUID主键的3到10倍,相差比较明显,特别是update小范围之内的数据上面。

6、在备份恢复上,自增ID主键稍微优于UUID。


自增ID主键+步长,适合中等规模的分布式场景


在每个集群节点组的master上面,设置(auto_increment_increment),让目前每个集群的起始点错开 1,步长选择大于将来基本不可能达到的切分集群数,达到将 ID 相对分段的效果来满足全局唯一的效果。



UUID,适合小规模的分布式环境


对于InnoDB这种聚集主键类型的引擎来说,数据会按照主键进行排序,由于UUID的无序性,InnoDB会产生巨大的IO压力,而且由于索引和数据存储在一起,字符串做主键会造成存储空间增大一倍。


在存储和检索的时候,innodb会对主键进行物理排序,这对auto_increment_int是个好消息,因为后一次插入的主键位置总是在最后。


但是对uuid来说,这却是个坏消息,因为uuid是杂乱无章的,每次插入的主键位置是不确定的,可能在开头,也可能在中间,在进行主键物理排序的时候,势必会造成大量的 IO操作影响效率,在数据量不停增长的时候,特别是数据量上了千万记录的时候,读写性能下降的非常厉害。




作者丨唐宋缘明卿_cris

来源丨网址:https://blog.csdn.net/qq_30108237/article/details/106856051

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn


跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

自增ID UUID 性能对比
相关文章