写点什么

掉坑了!GROUP_CONCAT 函数引发的线上问题

用户头像
AI乔治
关注
发布于: 2021 年 04 月 23 日
掉坑了!GROUP_CONCAT函数引发的线上问题

本文分享一篇在工作遇到的一个问题,关于 MySQL GROUP_CONCAT 函数导致的问题。希望能帮忙到你。

业务场景

在说遇到的坑之前,先描述一下大致的业务场景。系统有一个排班的功能,一个医生一天可以排多种业务类型的排班,并且每一种业务类型的排班都支持排个多时段(时段的最小单位是 15 分钟)。

举例:D 医生在 2020-12-31 的 8:00~10:00、10:30~12:00  排班了【在线 A】 和 【在线 B】业务。

【在线A】 2020-12-31 8:00~10:00【在线A】 2020-12-31 10:30~12:00【在线B】 2020-12-31 8:00~10:00【在线B】 2020-12-31 10:30~12:00
复制代码

在查询这个一天排班的数据,伪 SQL 方便理解:

SELECT dt, biz_type, GROUP_CONCAT(  CONCAT_WS('|', id, start_time, end_time) ) AS multiPeriodDetailFROM doctor_schedule_detailWHERE doctor_id = '456231'AND dt = '2020-12-30'GROUP BY doctor_id, biz_type, dt
复制代码

CONCAT_WS(’|’, id, start_time, end_time)中的字段说明:

  • id:时段的 id

  • start_time:时段开始时间

  • end_time:时段结束时间

对数据进行分组后,使用 CONCAT_WS 函数 指定分隔符进行参数拼接。然后使用 GROUP_CONCAT 函数 返回分组中字符串结果组合连接的值,默认缺省为一个逗号 (",")进行分隔,这个缺省值可以去掉,本例子中使用默认缺省值。

查询后结果展示如下:

查询结果至此场景描述结束。

遇到的坑

这个代码在线上已经运行很长了,有一天用户反馈说给 D 医生排班了,但是界面查不到这个时段的排班数据。

经过"紧张激烈"的排查,终于找到了这个问题的罪魁祸首。

如上场景描述,在查询 SQL 中使用了 GROUP_CONCAT 函数,在业务中因为排班的最小时段为:单位是 15 分钟。正常医生不会拍很多很细的班,但在特殊的场景中,有一些医生就是 15 分钟排一次班,而且系统中真实的 CONCAT_WS 函数拼接返回的字段比较多,那么导致查询出来的数据非常多, GROUP_CONCAT 函数就就大于默认值得数据丢弃了。

注:GROUP_CONCAT 对应的配置参数 group_concat_max_len 默认设置最大的长度 1024 字节。

查询 group_concat_max_len 配置:

show variables like "group_concat_max_len";
复制代码

tips:字段内容字节长度

MySQL utf-8 编码集, 一个中文占 3 个字节。

-- 字符长度 输出结果:6SELECT CHAR_LENGTH("你好2021")-- 字节长度 输出结果:10SELECT LENGTH("你好2021")
复制代码

解决方案

在知道问题原因后,就有了对应的解决方案。第一种方案:修改 Mysql 的配置,调整 group_concat_max_len 的值。

1 方法一:在MySQL的配置文件中加入如下配置(推荐):2 3 group_concat_max_len = 1024004 方法二:更简单的操作方法,执行SQL语句:5 6 SET GLOBAL group_concat_max_len = 102400;7  8 SET SESSION group_concat_max_len = 102400;9
复制代码

生产环境,肯定要用方法一:在 MySQL 的配置文件。但考虑生产环境修改配置需要走一些流程和审批,于是有了第二种方案的考虑。

第二种方案:进行业务功能的调整,需求的调整或者 GROUP_CONCAT 拼接少返回一些数据

功能已经上线,此时在修改,对业务有一定的影响综合考虑后,决定更改 group_concat_max_len 的值,经过对业务的分析计算出具体要更改的值。

结语

在真实场景中,大多数问题的解决方案不止一种,在权衡后找到一个符合当时的问题的最优解决方案。

看完三件事❤️

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。

  • 关注公众号 『 java 烂猪皮 』,不定期分享原创知识。

  • 同时可以期待后续文章 ing🚀


作者:阿飞云

出处:https://club.perfma.com/article/2367188

用户头像

AI乔治

关注

分享后端技术干货。公众号【 Java烂猪皮】 2019.06.30 加入

一名默默无闻的扫地僧!

评论

发布
暂无评论
掉坑了!GROUP_CONCAT函数引发的线上问题