MySQL中UUID主键的优化
UUID(Universally Unique IDentifier 通用唯一标识符),是一种常用的唯一标识符,在MySQL中,可以利用函数uuid()来生产UUID。因为UUID可以唯一标识记录,因此有些场景可能会用来作为表的主键,但直接用UUID来作为主键可能存在性能缺陷,我们需要采取一些优化手段。
目录
一、UUID主键的缺陷
二、优化方案
一、UUID主键的缺陷
在MySQL中,innodb是按照表的聚簇索引(主键)来组织数据存储的,也就是主键的顺序决定了数据存储的顺序。这也是为什么我们通常推荐用整型,自增的数字来作为表的主键,当新数据插入时,主键一定是最大的,只要放在叶子层中最后的数据页即可,对已有的数据不会有影响。
而如果用UUID来做主键,则会有2个缺陷:
- UUID的值是随机的,因此新插入的数据有可能会插到已有数据的中间,这会导致整个索引树的重新平衡和节点分裂,降低插入性能,数据量越大越严重。
- UUID是字符型,相对数字占用的存储空间很大,这意味着主键很大,而主键又会附加到所有的二级索引中,因此所有的索引都很臃肿,消耗额外的磁盘和内存资源,降低查询性能。
UUID的生成方式有很多版本,这里举2个最常用的:
- UUID V1: 通过时间戳和MAC地址来生成,可以生成顺序的UUID。
- UUID V4: 通过随机数来生成,无法生成顺序的UUID。
MySQL自带的函数uuid()是通过UUIDv1生成,因此上面第一个缺陷通常不存在,你需要注意的是某些应用是否会自己生成非顺序的UUID插入表中。
下面通过示例来看差别,我们创建两张结构一样的表,一张用数字作为主键,一张用UUID作为主键:
create table digital_pk(
id int auto_increment primary key,
serial int);create table uuid_pk(
id varchar(36) default(uuid()) primary key,
serial int); 
我们分别向2张表中插入5条数据:
insert into digital_pk(serial) values(1);
insert into digital_pk(serial) values(2);
insert into digital_pk(serial) values(3);
insert into digital_pk(serial) values(4);
insert into digital_pk(serial) values(5); 
insert into uuid_pk(serial) values(1);
insert into uuid_pk(serial) values(2);
insert into uuid_pk(serial) values(3);
insert into uuid_pk(serial) values(4);
insert into uuid_pk(serial) values(5); 
我们通过explain来查看索引的信息:
-
explain select * from digital_pk where id=1\G

explain select * from uuid_pk where id='71b49d70-7f98-11ee-a9a1-0050569c9844'\G 
可以看到uuid作为主键的长度是146,而数字做主键的长度为4,这意味着当数据量非常大的时候,UUID的索引会非常臃肿,查询性能会很低。
二、优化方案
虽然通常不推荐使用UUID作为表的主键,但某些场景如果我们必须要用UUID作为主键,我们也可以通过一些方法来规避上述缺陷。
MySQL为了优化UUID的存储,专门提供了两个函数:
- uuid_to_bin(uuid, swap_flag),将字符型UUID转换为二进制UUID,转换后返回的数据类型是varbinary。
- bin_to_uuid(uuid, swap_flag),将二进制UUID转换为字符型UUID
在存储的时候用uuid_to_bin(uuid, swap_flag)将UUID由字符型转化为二进制,可以大大缩小索引的长度,函数中的swap_flag有2个取值:
- 0 代表转换后的数据依然是和UUID字符排序相同
- 1 代表转换后将UUID中的time-low和time-high部分(第一和第三组)交换位置,转换后数据可以按时间连续递增,对InnoDB的聚簇索引还会有性能提升。注意这个仅对UUID V1版本基于时间戳生成的UUID才有效,如果是其他类型的UUID,不会得到性能提升。
下面我们利用这个函数新建一个表uuid_pk_v2:
create table uuid_pk_v2(
id binary(16) default(uuid_to_bin(uuid(),1)) primary key,
serial int); 
- 这里id列的数据类型变成了binary(16),同时uuid在存储时转换为二进制型存储。
插入1条数据
-
insert into uuid_pk_v2(serial) values(1);

select id, serial from uuid_pk_v2;
select bin_to_uuid(id,1), serial from uuid_pk_v2; 
- 直接查询是以16进制显示的数据,这对我们没有意义,我们需要用bin_to_uuid()函数将数据还原为字符串型UUID。
我们再看一下索引:
explain select * from uuid_pk_v2 where id=uuid_to_bin('a292725f-7fa1-11ee-a9a1-0050569c9844',1)\G 
- 索引的长度从164缩短为16,只有原来的十分之一,这代表索引在磁盘和内存占用的空间也会缩小至十分之一,扫描速度会快的多。
- 因此,虽然在插入和查询的时候多了一层函数的处理,但是这可以完美解决前面UUID的两个缺陷,带来的性能提升是完全值得的。
相关文章:
MySQL中UUID主键的优化
UUID(Universally Unique IDentifier 通用唯一标识符),是一种常用的唯一标识符,在MySQL中,可以利用函数uuid()来生产UUID。因为UUID可以唯一标识记录,因此有些场景可能会用来作为表的主键,但直接…...
Python实现WOA智能鲸鱼优化算法优化BP神经网络分类模型(BP神经网络分类算法)项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…...
Rust语言代码示例
安装Rust语言,然后创建一个新的Rust项目。接下来,你需要安装一个名为"requests"的Rust包,这个包可以帮助你发送请求。然后,你需要安装一个名为"rust-crawler"的Rust包,这个包可以帮助你编写爬虫程…...
【SpringBoot3+Vue3】一【基础篇】
目录 一、Spring Boot概述 1、Spring Boot 特性 1.1 起步依赖 1.2 自动配置 1.3 其他特性 1.3.1 内嵌的Tomcat、Jetty (无需部署WAR文件) 1.3.2 外部化配置 1.3.3 不需要XML配置(properties/yml) 二、Spring Boot入门 1、一个入门程序需求 2、步骤 2.1 创建Maven工…...
麒麟信安登录央视,深度展现为中国信息安全铸“魂”之路
麒麟信安登录央视,深度展现为中国信息安全铸“魂”之路 近日,麒麟信安登录央视频道,《麒麟信安——为中国信息安全铸“魂”》在CCTV-4中文国际频道、CCTV-7国防军事频道、CCTV-10 科教频道、CCTV-12社会与法频道、CCTV-17农业农村频道&#x…...
Flutter的专属Skia引擎解析+用法原理
Skia是一款跨平台的2D图形库,是Google公司开发的,可以用于开发各种应用程序,如浏览器、游戏、移动应用程序等。Skia引擎的主要特点是速度快、可移植性强、占用的内存少、稳定性佳,适用于多种硬件平台。 Skia的目标是提供快速、高…...
python poetry的教程
Poetry Python世界中,Poetry是一个近年来备受瞩目的工具,它为开发者提供了一个灵活且强大的依赖管理解决方案。Poetry可以帮助开发者管理项目的依赖关系,同时提供了一系列的工具和功能,使开发者能够更轻松地创建和管理复杂的项目。…...
jq里的ajax超详细参数讲解
目录 1、url:要发送请求的URL地址。 2、type:请求的类型,可选参数,包括GET、POST、PUT、DELETE等,默认为GET。 3、data:要发送到服务器的数据,可以是一个字符串、数组或对象。默认为null。 4…...
郑州大学2020级信息安全专业——保研小结
最终上岸 夏令营: 夏令营开始的时间一般比较早,在期末考试之前就已经开始了,需要提前联系导师,有的学校是弱com,导师愿意要你入营的概率和优营的概率就会比较大,因此要提前联系导师,复习好项目…...
【系统架构设计】架构核心知识: 3.6 负载均衡和Session
目录 一 负载均衡 1 应用层负载均衡 2 传输层负载均衡 二 Session 1 Session共享机制...
python pip安装特定包,网络慢的问题
文件requirements.txt httpx0.24.0 Pillow9.5.0 playwright1.33.0 tenacity8.2.2 tornado6.3.2 PyExecJS1.5.1 opencv-python4.7.0.72 tortoise-orm[asyncmy]0.19.3 aerich0.7.2 numpy~1.24.4 redis~4.6.0 Pydantic1.7将文件放入任意一个目录下 cd 到该目录下执行 while read…...
CMT2300A超低功耗127-1020MHz Sub-1GHz全频段SUB-1G 射频收发芯片
CMT2300A超低功耗127-1020MHz Sub-1GHz全频段SUB-1G 射频收发芯片 Sub-1GHz,是指小于1GHz频率的统称。Sub-1GHz无线电频段应用的主要特点:(1)频率较低波长较长,传输距离远,穿透性强;࿰…...
设计模式之工厂模式 ( Factory Pattern )(1)
其他设计模式也会后续更新… 设计模式其实需要有一定开发经验才好理解,对代码有一定的设计要求,工作中融入才是最好的 工厂模式 ( Factory Pattern ) 工厂模式(Factory Pattern)提供了一种创建对象的最佳方式 工厂模式在创建对…...
OpenCV入门11:轮廓提取和形状识别
轮廓分析主要用于轮廓提取和形状识别等任务。在OpenCV中,轮廓提取和形状识别是图像处理和计算机视觉中常见的任务。下面是关于这两个知识点的一些基本内容: 轮廓提取: 轮廓提取是指从图像中提取出物体轮廓的过程。在OpenCV中,可…...
竞赛选题 深度学习疲劳检测 驾驶行为检测 - python opencv cnn
文章目录 0 前言1 课题背景2 相关技术2.1 Dlib人脸识别库2.2 疲劳检测算法2.3 YOLOV5算法 3 效果展示3.1 眨眼3.2 打哈欠3.3 使用手机检测3.4 抽烟检测3.5 喝水检测 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习加…...
Java编程--定时器/线程池/工厂模式/ ThreadPoolExecutor
前言 逆水行舟,不进则退!!! 目录 什么是定时器 实现一个定时器 自己实现一个定时器 什么是线程池 线程池的使用: 什么是工厂模式? 自己实现一个线程池: ThreadPoolExecutor 类…...
【python】Django——django简介、django安装、创建项目、快速上手
笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ Django基础——django安装、创建django项目、django快速上手 django简介django安装1. conda创建环境pydjango2. pip安装django3. django目录 创建项目1. 打开终端(cmd)2. 进入某个目录3.创建项目命令4.django项目…...
未来之选:为什么向量数据库是您的数据管理利器
文章目录 前言什么是向量数据库?向量数据库的机制向量数据库的优点查询向量数据库 什么是向量Embedding?Amazon OpenSearch Service总结 前言 向量数据库擅长处理复杂的高维数据,正在彻底改变商业世界的数据检索和分析。它们执行相似性搜索…...
隧道施工工艺流程vr线上虚拟展示成为产品3D说明书
行业内都知道,汽车生产的大部分都需要冲压加工来完成,因此汽车冲压工艺是汽车制造过程中的重要环节,传统的展示方式往往局限于二维图纸和实地操作,难以充分展现工艺的细节和流程。然而,随着技术的进步,汽车…...
Nacos(含安装)
Nacos是一个开源的动态服务发现、配置和管理平台。它提供了服务发现、服务健康检查、动态配置管理、服务元数据管理等功能,支持多种服务发现和注册方式。Nacos可以帮助开发者快速构建一个具有弹性和高可用性的微服务应用程序。Nacos的全称是Named after Configurati…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
