You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MariaDB多字段GROUP BY关联LEFT JOIN SUM返回NULL异常问题

问题结论

该问题不是索引设置错误,属于MariaDB已知内核bug MDEV-26337。触发条件是GROUP BY的多个列都存在独立单列索引时,优化器会选择松散索引扫描策略加速分组运算,该策略在处理分组键前缀连续重复的场景时存在逻辑缺陷,会错误跳过部分分组结果,因此你会遇到相邻行sales_order_id相同时匹配不到结果返回NULL的情况。你删除sales_order_id索引、用concat拼接分组键的操作本质都是破坏了松散索引扫描的触发条件,所以结果恢复正常。

可落地解决方案

  • 方案1:临时关闭当前会话的松散索引扫描优化,对性能影响极小,适合不想改表结构、不想升级的场景,执行查询前先运行:
SET SESSION optimizer_switch='loose_index_scan=off';

再运行你的原始查询即可得到正确结果。

  • 方案2:创建联合索引优化查询性能,同时绕过bug,适合长期使用的业务查询:
    给tr_sales_order_detail表创建分组字段的联合索引,优化器会优先选择联合索引执行分组,不会触发松散索引扫描bug,同时分组不需要回表,查询性能比原有单列索引更高:
CREATE INDEX idx_so_detail_group ON tr_sales_order_detail(item_id, row_id, sales_order_id);
  • 方案3:升级MariaDB到修复版本,适合可以做版本升级的场景
    该bug已经在以下版本完成修复:10.3.36、10.4.26、10.5.17、10.6.9、10.7.5及更高迭代版本,升级后无需修改任何查询语句或索引即可正常运行。
  • 方案4:修改查询语句绕过优化器选择,适合临时调整不想改配置的场景
    在子查询的GROUP BY语句后添加ORDER BY NULL即可破坏松散索引扫描的触发条件,修改后的完整查询如下:
SELECT
tr_sales_delivery_detail.sales_order_id,
tr_sales_delivery_detail.row_id,
tr_sales_delivery_detail.qty_delivery,
so.qty AS so_qty
FROM tr_sales_delivery_detail
LEFT JOIN (
    SELECT tr_sales_order_detail.item_id, 
             tr_sales_order_detail.row_id,  
             tr_sales_order_detail.sales_order_id,
             SUM(tr_sales_order_detail.qty) AS qty FROM tr_sales_order_detail
    GROUP BY tr_sales_order_detail.item_id, tr_sales_order_detail.row_id, tr_sales_order_detail.sales_order_id
    ORDER BY NULL
) so
ON so.item_id = tr_sales_delivery_detail.item_id
AND so.row_id = tr_sales_delivery_detail.row_id
AND so.sales_order_id = tr_sales_delivery_detail.sales_order_id
WHERE tr_sales_delivery_detail.sales_delivery_id = '10923';

内容的提问来源于stack exchange,提问作者Tryanto I

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:54:04