背景

今天被同事找来讨论一个数据库问题,一个select语句带有聚合函数GROUP_CONCAT(countryCode),countryCode是纯数字,所以这一列出来的结果应该是这样的:24,25,1003,1004,1025,......,但是实际上结果被截断了,把结果copy出来到notepad++,发现每一条记录的长度都是341

经过一番查询,发现mysql对这个函数有个配置:group_concat_max_len,指的是对GROUP_CONCAT()函数的结果进行截断。比如group_concat_max_len=1024,那么mysql会对该函数的结果截取前1024个字节(Byte)。看起来就是它了。

通过以下命令,可以查看该库对应的配置:

show variables like 'group_concat_max_len'

>> 1024

可见我们的库也是1024,那为啥实际结果长度只有341呢。据回答的小哥说:当GROUP_CONCAT()Order By一起使用的时候,结果就会进一步裁剪到1/3,如果去掉Order By条件,结果长度会是1024。但是这个规律是实践出来的,具体为啥会这样,官方手册里并没有说。

验证

为了验证思路,可参考以下sql进行配置

# SESSION 表示变动只影响当前会话
SET SESSION group_concat_max_len=102400;

配置后验证结果长度确实不会被截断了。

修复

由于我们只在某一个环境中才复现了这个问题,别的环境都没问题,所以思路就是参考别的环境的配置,经查询发现其他环境的值都是group_concat_max_len=8192,所以其他环境没有这个问题,遂对齐配置即可。

# GLOBAL 表示变动影响全局
SET GLOBAL group_concat_max_len=your_value_here;

如果严谨一点,应该需要排查项目里所有用到GROUP_CONCAT()的地方,然后结合业务评估一下合理的大小,再找DBA协商进行变更。所幸我们生产环境配的是102400,足够大了,也就没这种顾虑了。


参考: