MySQL 8.0.33查询JSON列报排序内存不足问题求助
问题分析与解决方案
首先可以明确:这大概率不是MySQL 8.0的Bug,核心问题出在查询的排序效率以及资源配置的生效逻辑上,下面分点说明:
1. 为什么调大sort_buffer_size没生效?
你修改的是global级别的sort_buffer_size,这个设置只会对新创建的数据库会话生效,当前正在使用的会话不会自动加载新的全局配置。如果要让当前会话生效,需要手动执行:
SET sort_buffer_size = 1048576; -- 示例:设置为1MB,可根据实际情况调整到4MB甚至更大
不过更关键的是:单纯调大排序缓冲区只是治标,真正的问题是你的查询可能在做全表排序,数据量一旦大起来,再大的内存也不够用。
2. 最有效的优化:给created_at加索引
你的查询需要按created_at倒序排序并取前10条,如果created_at字段没有索引,MySQL需要扫描全表,把所有数据加载到内存(或磁盘)中进行排序,这会极大消耗排序缓冲区,甚至触发磁盘排序,效率极低。
创建索引的语句:
CREATE INDEX idx_campaigns_created_at ON campaigns(created_at DESC);
加了这个索引后,MySQL可以直接通过索引的顺序获取数据,完全不需要额外的排序操作,自然也就不会触发“排序内存不足”的报错,这才是治本的方案。
3. JSON查询的语法简化(可选)
MySQL 8.0支持更简洁的->>运算符,等价于json_unquote(json_extract(...)),可以把你的查询语句简化为:
SELECT `campaigns`.`model`->>'$.migration' AS `migration` FROM `campaigns` ORDER BY `created_at` DESC LIMIT 10 OFFSET 0;
这个优化主要是让代码更简洁,对性能的提升有限,但推荐使用。
4. 如何验证是否是Bug?
如果给created_at加了索引之后,仍然出现相同的报错,那才需要考虑是否是MySQL 8.0的Bug。此时可以:
- 检查MySQL官方的Bug列表,确认是否有同版本的类似问题
- 尝试升级到更高版本的MySQL 8.0(比如8.0.36+),看问题是否消失
- 提交Bug报告到MySQL官方
内容的提问来源于stack exchange,提问作者superfive33
相关产品推荐
相关产品推荐

