MariaDB 10.5关联GROUP_CONCAT超70条ID时返回NULL问题
MariaDB 10.5升级后GROUP_CONCAT关联查询异常问题解决
环境说明
- 本地环境:MariaDB 10.5
- 服务器环境:从MariaDB 10.3升级至10.5(主从复制架构)
问题描述
存在一个多关联的复杂查询,大量使用GROUP_CONCAT函数,简化后语句如下:
SELECT editions_data.editionNames, editions_data.editionIds, p.id FROM product p LEFT JOIN (SELECT GROUP_CONCAT( `e`.name SEPARATOR ",") AS `editionNames`, GROUP_CONCAT( `e`.id SEPARATOR ",") AS `editionIds`, pe.product_id as productId FROM products_editions pe LEFT JOIN editions e ON e.id = pe.edition_id GROUP BY pe.product_id ) as editions_data ON p.id = editions_data.productId WHERE p.id IN (...)
本地环境及服务器10.3版本下运行正常,但升级至10.5后出现异常:
- 当
IN子句传入70个ID时,所有行返回正确数据; - 传入71个及以上ID时,仅第一行数据正确,其余行的
editions_data字段均为NULL。
已交换第70、71个ID测试,排除数据本身问题,异常仅在ID数量≥71时触发。
结果对比
70个ID时返回结果:
editionNames | editionsIds | p.id rock oldies | 1 | 1 rock oldies | 1 | 2 indies | 2 | 3
71个及以上ID时返回结果:
editionNames | editionsIds | p.id rock oldies | 1 | 1 null | null | 2 null | null | 3
两台服务器的group_concat_max_length参数均为1048576。
解决方案
1. 重构查询语句(推荐)
将子查询聚合改为主查询直接分组聚合,避免子查询提前聚合后匹配异常:
SELECT GROUP_CONCAT(e.name SEPARATOR ",") AS editionNames, GROUP_CONCAT(e.id SEPARATOR ",") AS editionIds, p.id FROM product p LEFT JOIN products_editions pe ON p.id = pe.product_id LEFT JOIN editions e ON e.id = pe.edition_id WHERE p.id IN (...) GROUP BY p.id
该写法直接基于主查询的产品ID分组,消除了子查询与主查询大数量ID匹配时的优化器异常。
2. 强制关联顺序
MariaDB 10.5优化器逻辑有调整,可能在大数量IN子句匹配时选择了异常的关联策略。使用STRAIGHT_JOIN强制指定关联顺序:
SELECT editions_data.editionNames, editions_data.editionIds, p.id FROM product p STRAIGHT_JOIN (SELECT GROUP_CONCAT( `e`.name SEPARATOR ",") AS `editionNames`, GROUP_CONCAT( `e`.id SEPARATOR ",") AS `editionIds`, pe.product_id as productId FROM products_editions pe LEFT JOIN editions e ON e.id = pe.edition_id GROUP BY pe.product_id ) as editions_data ON p.id = editions_data.productId WHERE p.id IN (...)
STRAIGHT_JOIN会强制按照FROM子句的顺序执行表关联,规避优化器的异常选择。
3. 排查主从执行计划一致性
由于是主从架构,分别在主从库执行EXPLAIN语句对比执行计划,确认是否因主从优化器参数差异导致问题,若存在差异需统一参数配置。
内容的提问来源于stack exchange,提问作者tttpapi
相关产品推荐
相关产品推荐

