MySQL中JSON的存储原理(mysql中json字段操作)
liuian 2025-07-06 14:06 36 浏览
前言:表中有json字段后,非索引查询性能变得非常糟糕
起因是我有一张表,里面有json字段后,而当mysql表中有200w数据的时候,走非索引查询性能变得非常糟糕需要3到5s。因此对mysql的json类型做了梳理
先说建表建议
对于大宽主表的建表的建议是,拆成2个表,把需要用来查询的字段放到主表,其他的字段全部放在扩展表。varchar类型的字段,长度尽可能短
一、JSON在硬盘中的存储原理
MySQL采用二进制格式存储的 JSON 值,在磁盘存的是doc对象,内含type & value。
doc ::= type value
type ::=
0x00 | // small JSON object
0x01 | // large JSON object
0x02 | // small JSON array
0x03 | // large JSON array
0x04 | // literal (true/false/null)
0x05 | // int16
0x06 | // uint16
0x07 | // int32
0x08 | // uint32
0x09 | // int64
0x0a | // uint64
0x0b | // double
0x0c | // utf8mb4 string
0x0f // custom data (any MySQL data type)
value ::=
object |
array |
literal |
number |
string |
custom-data- MySQL对JSON对象存储是分段的,存储的最前面为存放当前对象的元素个数,以及整体占的大小
- type主要是标识类型(大json对象、小json对象、大json数组、小json数组、literal、int16、uint16、int32、uint32、int64、uint64、double、string、custom自定义类型);
- value包含object、array、literal、number、string、custom-data(与type类型对应);
- 当需要读取JSON值的时候,二进制格式的结构使服务器能够直接通过键或数组索引查找子对象或嵌套值,而无需读取文档中它们之前或之后的所有值。
- 当需要写JSON值的时候,从二进制形式转换到内存中的结构化DOM,并使用JSON值的递归树表示与解析树紧密对应;
二、JSON在内存中的占据空间原理
对于varchar(255) 类型的字段,硬盘上是按照真实空间存储,而加载到内存中后,内存中的长度是varchar定义的长度255存储
JSON在内存中占用的空间资料没查到,但是应该是根据实际空间占用,因为json中存了实际长度
三、JSON类型最大长度和溢出页的概念
JSON最大存储长度为4G,但是实际能存多少还取决于mysql设置的一次更新最大包的大小(默认1M),
思考下Innodb聚簇索引的特征, 会建立一个主键索引并把整行数据放到一起。那么如果有一个字段是JSON类型或者Text或者varchar(1000)这种长字段的存在,是否会应为一行数据太大,mysql一页16K会不会放不下?
即使放下了 走主键索引是否会太慢?
先说结论,
第一、mysql一页16K至少可以放了两条数据
第二、mysql有一个行溢出的概念, 5.7之后的默认行格式为dynamic,特点是对于VARCHAR(M)、Text、JSON类型的数据,只在聚簇索引行存放真实数据的地址。而真实的数据放到溢出页里面。这样就能保证16K一页能尽可能密集,进而提升索引查询效率
添加图片注释,不超过 140 字(可选)
看到这应该能理解为何用非索引查询很慢,原因是要跳转寻找真实数据
四、JSON索引
MySQL 5.7 针对JSON的索引做了优化,具体方式就是通过生成列来实现JSON某个字段的索引。通俗的来说就是针对JSON指定的列抽取出来,通过冗余该字段的方式来实现索引
目前支持两种生成列形式,即Virtual Generated Column(虚拟生成列)和Stored Generated Column(存储生成列),支持在生成列上定义二级索引(不能与普通列定义联合索引),仅支持本表的非生成列上定义生成列。
- Virtual Generated Column不会将这一生成列的数据持久化到磁盘上(仅将虚拟列的元数据信息存在于相关系统表中),不支持针对虚拟列进行Update & Insert 的操作。在对应普通列Insert和Update操作时会消耗额外的写负载,因为更新虚拟生成列索引时需要将衍生列值计算出来,并写到索引里;这样就避免了每次读取数据行时都需要进行一次衍生计算。
- Stored Generated Column 会将数据持久化到磁盘上,在存储生成列上定义索引其实和普通列上定义索引无区别,性能上也不如虚拟索引,会导致聚簇索引变得更大更占空间。
-- 定义虚拟生成列
ALTER TABLE `user` ADD COLUMN `v_sign_time` BIGINT ( 20 )
GENERATED ALWAYS AS ( attachment -> '$.sign_time' ) Virtual NULL AFTER attachment;
-- 定义索引
ALTER TABLE `user` ADD INDEX `idx_sign_time` (`v_sign_time`);相关推荐
- 系统光盘镜像下载(系统光盘镜像文件转换到u盘)
-
要在虚拟机中使用映像文件,需要先将映像文件下载到本地计算机上,然后将其上传到虚拟机中。以下是下载映像文件的步骤:1.打开虚拟机管理软件,例如VMwareWorkstation或Virtual...
- ghost系统盘制作(制作ghost启动盘)
-
首先,需要准备东西如下:光驱起码要支持DVD刻录吧,您要是Combo刻CD还真不好意思和别人打招呼。。。DVD白盘若干,一张随便什么样的可引导系统盘(里面有ghost的那种),nero软件,Ultra...
- cad2008序列号和激活码(cad2008序列号密钥)
-
2008cad注册码是666-98989898。双击“AutoCAD2008Chs_运行获取激活码.exe”,将注册界面上的申请号粘贴到“AutoCAD2008Chs_运行获取激活码.exe”申请号一...
-
- 电脑无线网连不上怎么办(电脑无线网连接不上怎么回事)
-
1、打开“控制面板”,点击“网络和Internet”。2、点击“网络和共享中心”。3、点击“更改适配器设置”。4、鼠标右键单击需要连接的网络,在弹出的对话框中,点击“属性”。5、选中“Internet协议版本4(TCP/IPv4)”,...
-
2025-11-28 23:55 liuian
- u盘如何恢复删除的文件(如何恢复u盘中被删除的文件)
-
如果您在使用WPS时误删了U盘文件,可以使用以下几种方法来恢复文件:1.检查回收站:首先检查一下您的回收站中是否有被误删的文件,如果有,可以将文件恢复回来。2.使用WPS数据恢...
- 推特官网入口(推特官网入口网页登录网址)
-
首先在浏览器中打开推特的官网,然后点击页面上的“注册”创建账号。Twitter可以让用户更新不超过140个字符的消息(除中文、日文和韩语外已提高上限至280个字符),这些消息也被称作“推文(Tweet...
- windows7如何清理c盘(win7怎么清理c盘)
-
1.打开桌面计算机,右键点击“C盘”,并选取“属性”。2.待新窗口弹出后,依次点击“工具”、“立即进行碎片整理”。3.最后,选取C盘,在按下“磁盘碎片整理”按钮,系统就会对C盘进行分析,并进行整理。4...
- win10自带分区工具(win10官方分区工具)
-
Win10自带的分区工具是磁盘管理器,可以用来创建、删除、格式化和调整磁盘分区。下面是使用磁盘管理器分区的步骤:1.打开磁盘管理器。您可以在Windows10搜索栏中输入“磁盘管理器”来快速打开。...
- appstore正版下载软件(apple store下载正版)
-
不会,他是正版的,因为只有ios系统可以用,但他里面的好游戏都是要收费的,所以打架都要越狱,去其它地方下载,不去商店的在安卓上,GooglePlayStore是类似于苹果的AppStore一...
- 手机锁屏密码键盘没了(手机输入密码的键盘没了怎么办)
-
如果手机锁屏密码的键盘找不到,首先要确认是否是由于软件问题导致的。可以尝试重启手机或者清理手机缓存来解决。如果问题仍然存在,可以尝试更换输入法或者恢复手机出厂设置来解决。如果以上方法都没有效果,建议联...
- 移动硬盘跟固态硬盘的区别(移动硬盘跟固态硬盘的区别是什么)
-
一:移动硬盘移动硬盘是指以传统机械磁盘作为存储介质,用于计算机之间交换大容量数据,讲究移动便携性的存储产品。优点:具有容量大、价格便宜的特点,方便存储大量文件数据。(推荐学习:web前端视频教程)缺...
- windows怎么截图快捷键(windows截图快捷键没反应)
-
1、按Prtsc键截图这样获取的是整个电脑屏幕的内容,按Prtsc键后,可以直接打开画图工具,接粘贴使用。也可以粘贴在QQ聊天框或者Word文档中,之后再选择保存即可。2、按Ctrl+Prtsc键截图...
- 显示器分辨率有哪几种(显示器屏幕分辨率都有哪些)
-
目前使用较多的显示器分辨率有640*480,800*600,1024*768,1280*1024四种。刷新率,这主要是指显示器显示画面每秒刷新的次数,现在的电脑显示屏刷新率一般为75Hz,如果刷新率在...
- windows7激活工具 知乎(win7激活工具怎么使用教程)
-
Win7激活工具有很多,比如kms激活工具、小马激活工具、Windowsloader等。下面以这三款激活工具为例,做一个简单的比较。1、kms激活工具,相对比较稳定,通用性强,对各种gho、iso镜...
- 一周热门
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
