如果我们使用大字符串作为 MySQL 索引键会发生什么

news2025/4/7 1:16:32

背景

正如我之前的文章里所解释的那样,B+树的深度决定了MySQL在仅考虑使用索引的情况下的最坏查询性能。在SSD的帮助下,拥有一个比4层更深的B+树应该是可以接受的。

那么下一个问题是:性能可能有多糟糕?在这里,我有意设计了一张表,使用非常长的字符串作为主键和索引,这将导致非常深的B+树,最多达到9层,以测试在SSD上的最差性能,这在实际生产中是不太可能遇到的。

环境

— 数据库
MySQL 版本:8.0.25
实例类型:AWS db.r5.large (2vCPUs, 16GiB RAM)
EBS 存储类型:通用 SSD (gp2)
— 测试客户端
Linux 内核版本:6.1
实例类型:AWS t2.micro (1 vCPU,1GiB 内存)

实验设计

1. 使用长字符串作为主键,并使用另一个长字符串列作为索引创建表格。我创建了9个表格,分别有5、25、125、625、3125、15625、78125和390625行。

为什么将表格的行数设置为等比数列,并且每个数字在另一个数字后乘以5?原因是在MySQL 8.0.25中,主键的大小应该小于3072字节,相当于3k。由于每个页面大小为16k,一个页面最多可以容纳5个键。因此,您可以期望在我们的索引B+树中,每个非分支节点最多有5个子节点。拥有5行的表格深度为2,25行的表格深度为3,依此类推...但在实际情况中可能更加复杂,因为页面目录的大小未确定,一些B+树的非分支节点可能只能容纳4个节点,使得树比理论更深。

CREATE TABLE `5_big_pk_test` (
`big_pk` varchar(768) NOT NULL,
`big_index_key` varchar(768) DEFAULT NULL,
`id` int NOT NULL DEFAULT '0',
PRIMARY KEY (`big_pk`),
KEY `query_by_big_key_index` (`big_index_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

这里我使用charset=utf8mb4,所以每个字符会占用4个字节。因此,长度为 768 的字符串足以达到主键大小限制的上限。

2. 插入不同行的表格。我使用测试客户端和复制来创建这些表。脚本可以在这里找到。

# test client
INSERT INTO {table} (big_pk, big_index_key) VALUES ({pk}, {pk})

big_key 和 big_index_key 的值是随机的长字符串。为了方便起见,该字符串由前 10 个字符的随机头和其余字符的固定尾组成。

3.使用测试客户端执行以下sql查询来测试性能。脚本可以在这里找到。

select * from {table} where big_pk = \"{target_key}\" --query by primary key
select * from {table} where big_index_key = \"{target_key}\" --query by index, but cause 2-times index tree lookup

4.查看innodb缓冲池状态

SHOW STATUS LIKE 'innodb_buffer_pool_pages%'

5.每次在表上测试完一定要重启数据库!刷新 innodb 缓冲池以避免读取旧缓存并得到错误结果!还需要设置以下变量以避免在重启期间缓冲池转储/加载。

# Stop saving the buffer pool to disk at shutdown
SET GLOBAL innodb_buffer_pool_dump_at_shutdown=OFF;
# Stop loading the buffer pool from disk at startup
SET GLOBAL innodb_buffer_pool_load_at_startup=OFF;

# Check the status of the dump and load
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_dump_status';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_load_status';

结果

查询 1。select * from {table} where big_pk = \"{target_key}\"

正如我们所见,B+ 树的深度按设计上升了。查询运行时最坏的情况是表有 390,625 行,大约需要 8ms 和 9 倍的 I/O 来查询其主键。

查询 2。select * from {table} where big_index_key = \"{target_key}\"

这个查询需要两次索引树查找,因为两次索引树都很深,所以会触发很多 I/O 步骤。最坏的情况仍然是 390,625 行的表,大约 15ms 和 14 倍的 I/O。

讨论

与浅树相比,在深 B+ 树上查询(8-15 毫秒)很慢。更糟糕的是,查询会消耗大量的I/O资源,其每秒查询率将受到IOPS/<每次查询的I/O操作数>的限制。以我的实例为例,IOPS基准是每秒3600次。因此,在390,625行表上进行的查询的每秒查询率将限制在250次/秒,更不用说我们还有其他需要同时进行I/O的查询。

此外,我从我的同事那里听说,当他们将大字符串(10个字符,40字节)用作索引时,数据库的CPU使用率非常高,因为它必须进行大量的字符串比较,这是CPU密集型操作。结果,团队不得不重新设计索引并执行DDL操作。他观察到在MongoDB上也存在这种情况,MongoDB也使用B-Tree索引。

我可以在MySQL上重现这个情况:在运行具有查询语句的两个进程后,当每秒查询率为1200时,CPU使用率已经达到17%。相比之下,对于整数键索引树上的查询语句,每秒查询率为2100时CPU使用率约为20%。

通常会创建集群索引(辅助索引)以加快某些查询的速度。在这些索引中,键的值被连接在一起以形成新的键,这可能导致索引的键变得很大。

结论

  1. 保持主键/索引键尽可能小。切勿使用长字符串作为主键/索引键。

  2. 设计集群索引时要小心。确保连接键足够小。


作者:YISHENG GONG

更多技术干货请关注公号“云原生数据库

squids.cn,基于公有云基础资源,提供云上 RDS,云备份,云迁移,SQL 窗口门户企业功能,

帮助企业快速构建云上数据库融合生态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/596701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

elasticsearch中文分词使用以及疑问

最近用到elasticsearch作为知识库底层搜索引擎&#xff0c;开发反馈中文查询有问题&#xff0c;所以引用ik分词解决此问题。 一、安装 根据自己的版本找到github仓库下载&#xff0c;我此处使用为7.9.3版本 v7.9.3 Releases medcl/elasticsearch-analysis-ik GitHub 解压到…

git pull 和push讲解:016

pull 和push大致流程&#xff1a;(将远程仓库同步到本地仓库)>(在本地仓库修改并提交)>(推送修改内容到远程仓库) 1. 首先创建一个文件夹&#xff0c; 打开Git Bash终端&#xff0c; cd到这个文件夹内 2. 将(远程仓库)的克隆到这个文件夹内&#xff1a;git clone 远程仓库…

史上最难HelloWorld

文章目录 TomcatServlet创建一个项目引入依赖创建目录编写代码打包部署验证 优化一下打包和部署-Smart TomcatServlet常见的问题 Tomcat Tomcat就是一个HTTP服务器&#xff0c;HTTP协议是前后端交互的桥梁&#xff0c;前端就是浏览器&#xff0c;后端就是一个HTTP服务器&#…

设计模式之~访问者模式

简述&#xff1a; 访问者模式表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 访问者模式(Vistor Pattern)是一种将数据结构与数据操作分离的的设计模式。 结构图&#xff1a; 实例&#xff1a; 示例代码&#x…

Linux系统下C语言的编程技巧

Linux系统能够为人们提供更加安全实用的效果,保证计算机系统能够稳定的运行。利用Linux系统下首先要进行C语言的编程,掌握编程的技巧能够更好的发挥计算机的作用。如何掌握Linux系统下计算机C语言的编程技巧是计算机发展的关键要素。本文对Linux系统下计算机C语言的编程技巧进行…

【复习笔记】FreeRTOS(三)任务挂起和恢复

本文是FreeRTOS复习笔记的第三节&#xff0c;任务挂起和恢复&#xff0c;使用的开发板是stm32f407VET6&#xff0c;创建两个任务&#xff0c;task1负责闪烁LED&#xff0c;task2负责按键控制&#xff0c;当按键按下时控制任务挂起&#xff0c;按键再次按下恢复任务&#xff0c;…

【数据结构】经典排序法

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析2 目录 &#x1f449;&#x1f3fb; 直接插入排序&#x1f449;&#x1f3fb; 选择排序&…

微信支付(小程序)-java

微信支付开发者文档微信支付是腾讯公司的支付业务品牌&#xff0c;微信支付提供公众号支付、APP支付、扫码支付、刷卡支付等支付方式。微信支付结合微信公众账号&#xff0c;全面打通O2O生活消费领域&#xff0c;提供专业的互联网行业解决方案&#xff0c;微信支付支持微信红包…

访问github网络问题解决

查看wsl可用镜像列表时产生如下访问github的网络问题 C:\Users\jiangcheng> wsl --list --online 无法从“https://raw.githubusercontent.com/microsoft/WSL/master/distributions/DistributionInfo.json”中提取列表分发。无法与服务器建立连接 Error code: Wsl/WININET_…

hive任务reduce步骤卡在99%原因及解决

我们在写sql的时候经常发现读取数据不多&#xff0c;但是代码运行时间异常长的情况&#xff0c;这通常是发生了数据倾斜现象。数据倾斜现象本质上是因为数据中的key分布不均匀&#xff0c;大量的数据集中到了一台或者几台机器上计算&#xff0c;这些数据的计算速度远远低于平均…

Vulkan Tutorial 9 模型加载Mipmaps

目录 28 加载模型 Sample mesh 加载顶点和索引 ​编辑 顶点去重 28 加载模型 我们将使用tinyobjloader库来从OBJ文件中加载顶点和面。它的速度很快&#xff0c;而且很容易集成&#xff0c;因为它是一个像stb_image一样的单文件库。将包含tiny_obj_loader.h的目录添加到Add…

ChatGPT国内镜像站

免费国内镜像推荐&#xff08;超稳定&#xff09; 下面为大家收集了目前国内最稳定流畅的ChatGPT镜像网站 目录 机器人 博弈ai 泰cool辣 道合顺 二狗问答 核桃 WOChat GPT中文站 TomChat 利用ChatGPTMindShow三分钟生成PPT ChatGPT国内镜像是啥 ChatGPT 镜像是指…

Xpdf 阅读器源码编译后查看文件中文乱码问题解决

经查阅&#xff0c;是由于缺少中文字体包&#xff1a; 第一步&#xff1a;下载所需要的字体包 下载https://dl.xpdfreader.com/xpdf-t1fonts.tar.gz 包含下载中文字体包&#xff08;非嵌入字体&#xff09; http://ftp.gnu.org/gnu/non-gnu/chinese-fonts-truetype/gkai00mp…

pytorch-简单回归问题-手写数字识别

pytorch-简单回归问题-手写数字识别 线性回归添加噪声简单例子分类问题引入-手写数字识别数据集 训练推导手写数字识别1加载数据集编写网络训练网络计算正确率 线性回归添加噪声 使用均方差损失函数来衡量损失 简单例子 通过最小化损失函数&#xff0c;求解出参数w b 下图表示…

封装的函数停发/启动CAN报文,以及报文接收检测,高可用

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe,博客目录大全,点击跳转👉 📘前言 🍅 在测试过程中,我们可能需要可控的停/发某些报文,今天博主给…

chatgpt赋能python:Python主页面的SEO分析及优化建议

Python主页面的SEO分析及优化建议 Python是一种高级编程语言&#xff0c;广泛应用于人工智能、数据分析、Web开发等领域。Python官方网站是Python社区的一个重要门户&#xff0c;为全球学习Python的开发者提供了全面、权威、可靠的信息。在这篇文章中&#xff0c;我们将分析Py…

Text to image论文精读SeedSelect: 使用SeedSelect微调扩散模型It’s all about where you start

随着文本到图像扩散模型的发展&#xff0c;很多模型已经可以合成各种新的概念和场景。然而&#xff0c;它们仍然难以生成结构化、不常见的概念、组合图像。今年4月巴伊兰大学和OriginAI发表《It’s all about where you start: Text-to-image generation with seed selection》…

软件外包开发项目原型图工具

项目原型图工具有非常重要的作用&#xff0c;尤其是在APP项目开发中&#xff0c;对于整体需求的表达是必不可少的工具。相比于传统的文档需求&#xff0c;图形文字的表达可以更清楚的表达需求&#xff0c;让客户清楚的明白软件功能有哪些&#xff0c;最后的界面是怎样的&#x…

微信海量数据查询如何从1000ms降到100ms?

&#x1f449;腾小云导读 微信的多维指标监控平台&#xff0c;具备自定义维度、指标的监控能力&#xff0c;主要服务于用户自定义监控。作为框架级监控的补充&#xff0c;它承载着聚合前 45亿/min、4万亿/天的数据量。当前&#xff0c;针对数据层的查询请求也达到了峰值 40万/m…

RL - 强化学习 上置信界算法 (UCB) 和 汤普森采样算法 (TS)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/130983835 上置信界算法和汤普森采样算法是两种解决多臂老虎机问题的经典方法。多臂老虎机问题是一种探索与利用的平衡问题&#xff0c;…