MySQL JSON_STORAGE_SIZE 怎样估算 JSON 文档占用空间
来源:17golang原创
时间:2026-10-18 10:09:31 330浏览 收藏
排查 JSON 列容量时,最容易混淆的是三个数字:原始字符串的字符长度、字符串按字符集编码后的字节数,以及 MySQL 把 JSON 解析成二进制表示后的存储字节数。标题里的 JSON_STORAGE_SIZE() 解决的是第三个问题。
官方文档:https://dev.mysql.com/doc/refman/8.4/en/json-utility-functions.html
要估算单个 JSON 值在 MySQL JSON 表示中的空间,直接对它调用JSON_STORAGE_SIZE()。如果参数是 JSON 列,结果应按“插入该值时的 JSON 存储大小”理解;发生部分更新后,再结合JSON_STORAGE_FREE()看可复用空间。它不是整张表的磁盘占用统计。
下面用一个很小的 JSON 文档把这个判断拆开。示例只用于说明 SQL 关系和返回字段,不把文中的示例结果当成某台服务器的运行截图。
先区分 JSON 文本长度和二进制存储大小
如果先用 CHAR_LENGTH() 或 LENGTH(),得到的是字符串层面的长度;它们适合检查输入文本,却不能直接代替 JSON 二进制存储大小。MySQL 需要先把合法 JSON 解析成自己的二进制表示,键名、数组、对象和标量会共同影响最终字节数。
因此,容量排查的第一个小项目目标不是计算整张表,而是对同一份 JSON 同时记录“输入文本”和“JSON 存储字节”两个字段:
-- 准备一份可重复比较的 JSON 文档,变量值必须是合法 JSON
SET @doc = '{"user_id":1001,"roles":["editor","reviewer"],"active":true}';
-- 把字符串层面的长度与 JSON 二进制表示的大小放在同一行观察
SELECT
CHAR_LENGTH(@doc) AS text_chars,
LENGTH(@doc) AS text_bytes,
JSON_STORAGE_SIZE(@doc) AS json_bytes;
这里的 json_bytes 才是这份 JSON 值经过解析后、按 JSON 二进制表示计算出的字节数。它和前两个字段不必相等,所以不要用字符串长度乘一个固定比例去推算所有文档。

用 JSON_STORAGE_SIZE 读取文档占用字节
把函数放到查询列里即可批量比较候选文档。参数可以是 JSON 列,也可以是能解析成 JSON 的字符串。对字符串参数,MySQL 会先解析再计算;参数为 NULL 时返回 NULL,参数不是合法 JSON 时则报错,这两个边界要和“返回 0”区分开。
-- 建立最小示例表,保留 JSON 类型以观察列级语义
CREATE TABLE json_size_demo (
id INT PRIMARY KEY,
payload JSON NOT NULL
);
-- 插入两个结构不同但都合法的 JSON 文档
INSERT INTO json_size_demo (id, payload) VALUES
(1, '{"name":"A","items":[1,2,3]}'),
(2, '{"name":"A","items":[1,2,3],"note":"longer value"}');
-- 返回每条 JSON 列值的存储字节数,便于按文档比较
SELECT
id,
JSON_STORAGE_SIZE(payload) AS json_bytes
FROM json_size_demo
ORDER BY id;
结果列只回答“这一列中的 JSON 文档在该函数语义下用了多少字节”。如果要做容量趋势,可以按业务维度分组后取样或汇总,但仍要注明这不是数据页、索引和压缩文件的完整大小。
JSON 列发生部分更新后,为什么结果要谨慎解释
JSON 列支持部分更新时,MySQL 可能在原有二进制空间中复用空闲区域。官方文档对列参数有一个很关键的限定:JSON_STORAGE_SIZE(json_col) 表示该 JSON 值插入列时使用的空间,而部分更新后留下的可用空间要看 JSON_STORAGE_FREE(json_col)。
-- 先对 JSON 列做一次局部替换,模拟文档内部字段变化
UPDATE json_size_demo
SET payload = JSON_SET(payload, '$.note', 'short')
WHERE id = 1;
-- 同时观察插入时大小语义与部分更新后的可复用空间
SELECT
id,
JSON_STORAGE_SIZE(payload) AS inserted_json_bytes,
JSON_STORAGE_FREE(payload) AS reusable_bytes
FROM json_size_demo
WHERE id = 1;
不要把 inserted_json_bytes 直接当成当前行在磁盘页里的精确占用,也不要把 reusable_bytes 当成已经归还给文件系统的空间。它们分别帮助你理解 JSON 值的初始二进制大小和部分更新留下的内部可复用空间。

把结果接进容量排查,而不是表空间估算
实际排查可以按下面的顺序落地:
- 先对采样 JSON 计算
JSON_STORAGE_SIZE(),确认不同结构和字符串长度的差异。 - 对 JSON 列同时观察
JSON_STORAGE_FREE(),判断是否存在部分更新留下的可复用空间。 - 如果问题是表目录增长,再单独查看表数据、索引、页分配、引擎和备份文件;不要把单列函数结果冒充整表统计。
这样做的好处是把“文档本身变大了吗”和“表在磁盘上为什么变大了”拆成两个可复查的问题。前者用 JSON 函数回答,后者需要数据库存储层指标配合。
常见疑问
JSON_STORAGE_SIZE(NULL) 会返回多少? 返回 NULL,不要把它当作零字节。若参数既不是 NULL 又不能解析成 JSON,则会报错。
它能直接告诉我表占了多少磁盘吗? 不能。它面向一个 JSON 值或 JSON 列值,表空间还可能包含行记录、索引、页内碎片、压缩和其他列。
为什么同样字符数的两个 JSON 结果不同? 键名、层级、数组/对象结构和标量类型都可能改变二进制表示;应以同一 MySQL 环境下的函数结果做比较。
总结一下:用 JSON_STORAGE_SIZE() 取得 JSON 值的二进制存储字节数,用 JSON_STORAGE_FREE() 补充部分更新后的可复用空间,再把表级磁盘问题交给存储层指标。这样既能定位 JSON 文档是否异常膨胀,也不会把一个单值函数误用成整表容量审计。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习