百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

别乱用UUID了,自增ID和UUID性能差距你测过吗?

csdh11 2025-02-06 14:30 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操作影响效率,在数据量不停增长的时候,特别是数据量上了千万记录的时候,读写性能下降的非常厉害。


  • 优点:搭建比较简单,不需要为主键唯一性的处理。
  • 缺点:占用两倍的存储空间(在云上光存储一块就要多花2倍的钱),后期读写性能下降厉害。

相关推荐

pdf怎么在线阅读?这几种在线阅读方法看看

pdf怎么在线阅读?我们日常生活中经常使用到pdf文档。这种格式的文档在不同平台和设备上的可移植性,以及保留文档格式和布局的能力都很强。在阅读这种文档的时候,很多人会选择使用在线阅读的方法。在线阅读P...

PDF比对不再眼花缭乱:开源神器diff-pdf助你轻松揪出差异

PDF比对不再眼花缭乱:开源神器diff-pdf助你轻松揪出差异在日常工作和学习中,PDF文件可谓是无处不在。然而,有时我们需要比较两个PDF文件之间的差异,这可不是一件轻松的事情。手动逐页对比简直是...

全网爆火!580页Python编程快速上手,零基础也能轻松学会

Python虽然一向号称新手友好,但对完全零基础的编程小白来讲,总会在很长时间内,都对某些概念似懂非懂,每次拿起书本教程,都要从第一章看起。对于这种迟迟入不了门的情况,给大家推荐一份简单易懂的入门级教...

我的名片能运行Linux和Python,还能玩2048小游戏,成本只要20元

晓查发自凹非寺量子位报道|公众号QbitAI猜猜它是什么?印着姓名、职位和邮箱,看起来是个名片。可是右下角有芯片,看起来又像是个PCB电路板。其实它是一台超迷你的ARM计算机,不仅能够运...

由浅入深学shell,70页shell脚本编程入门,满满干货建议收藏

不会Linux的程序员不是好程序员,不会shell编程就不能说自己会Linux。shell作为Unix第一个脚本语言,结合了延展性和高效的优点,保持独有的编程特色,并不断地优化,使得它能与其他脚本语言...

真工程师:20块钱做了张「名片」,可以跑Linux和Python

机器之心报道参与:思源、杜伟、泽南对于一个工程师来说,如何在一张名片上宣告自己的实力?在上面制造一台完整的计算机说不定是个好主意。最近,美国一名嵌入式系统工程师GeorgeHilliard的名片...

《Linux 命令行大全》.pdf

今天跟大家推荐个Linux命令行教程:《TheLinuxCommandLine》,中文译名:《Linux命令行大全》。该书作者出自自美国一名开发者,兼知名Linux博客LinuxCo...

PDF转换是难题? 搜狗浏览器即开即看

由于PDF文件兼容性相当广泛,越来越多的电子图书、产品说明、公司文告、网络资料、电子邮件选择开始使用这种格式来进行内容的展示,以便给用户更好的再现原稿的细节,但需要下载专用阅读器进行转化才能浏览的问题...

彻底搞懂 Netty 线程模型

点赞再看,养成习惯,微信搜一搜【...

2022通俗易懂Redis的线程模型看完就会

Redis真的是单线程吗?我们一般说Redis是单线程,是指Redis的网络IO和键值对操作是一个线程完成的,这就是Redis对外提供键值存储服务的主要流程。Redis的其他功能,例如持久化、异步删除...

实用C语言编程(第三版)高清PDF

编写C程序不仅仅需要语法正确,最关键的是所编代码应该便于维护和修改。现在有很多介绍C语言的著作,但是本书在这一方面的确与众不同,例如在讨论C中运算优先级时,15种级别被归纳为下面两条原则:需要的...

手拉手教你搭建redis集群(redis cluster)

背景:最近需要使用redis存储数据,但是随着时间的增加,发现原本的单台redis已经不满足要求了,于是就倒腾了一下搭建redistclusterredis集群。好了,话不多说,下面开始展示:...

记录处理登录页面显示: HTTP Error 503. The service is unavailable.

某天一个系统的登录页面无法显示,显示ServiceUnavailableHTTPError503.Theserviceisunavailable,马上登录服务器上查看IIS是否正常。...

黑道圣徒杀出地狱破解版下载 免安装硬盘版

游戏名称:黑道圣徒杀出地狱英文名称:SaintsRow:GatOutofHell游戏类型:动作冒险类(ACT)游戏游戏制作:DeepSilverVolition/HighVoltage...

Exchange Server 2019 实战操作指南

...