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

MySQL多表层级关联下嵌套GROUP BY生成层级JSON的性能问题求解

MySQL 嵌套JSON生成性能优化方案

你之前的写法性能差的核心原因是:内层子查询没有下推A表的过滤条件,MySQL会先对全量B、C表做关联分组生成所有B记录的JSON,再筛选出和目标AID匹配的记录,数据量大时耗时会非常高。

只需要将过滤条件下推到内层子查询,仅处理目标AID关联的B/C数据即可,性能可提升几个数量级,以下是两种可行实现:


方案1:显式下推过滤条件到子查询

SELECT JSON_OBJECT(
  'aid', a.id,
  'bs', IFNULL(JSON_ARRAYAGG(bjsons.bjson), JSON_ARRAY())
) AS a_json
FROM a
LEFT JOIN (
  SELECT 
    b.aid,
    JSON_OBJECT(
      'bid', b.id,
      'cs', IFNULL(JSON_ARRAYAGG(JSON_OBJECT('cid', c.id)), JSON_ARRAY())
    ) AS bjson
  FROM b
  LEFT JOIN c ON c.bid = b.id
  WHERE b.aid = 25 -- 下推AID过滤条件,仅处理目标A关联的B记录
  GROUP BY b.id
) AS bjsons ON bjsons.aid = a.id
WHERE a.id = 25
GROUP BY a.id

补充说明:加入IFNULL是为了处理没有关联B、C记录时返回空数组而非null的边界情况。


方案2:关联子查询写法(MySQL 8.0+ 适用)

这种写法逻辑更直观,MySQL优化器会自动下推过滤条件,不需要手动重复写过滤规则:

SELECT JSON_OBJECT(
  'aid', a.id,
  'bs', (
    SELECT IFNULL(JSON_ARRAYAGG(
      JSON_OBJECT(
        'bid', b.id,
        'cs', (
          SELECT IFNULL(JSON_ARRAYAGG(JSON_OBJECT('cid', c.id)), JSON_ARRAY())
          FROM c
          WHERE c.bid = b.id
        )
      )
    ), JSON_ARRAY())
    FROM b
    WHERE b.aid = a.id
  )
) AS a_json
FROM a
WHERE a.id = 25

额外性能优化建议

给关联字段加索引可以进一步提升查询速度:

-- 加速B表按AID过滤的速度
CREATE INDEX idx_b_aid ON b(aid);
-- 加速C表按BID关联的速度
CREATE INDEX idx_c_bid ON c(bid);

如果需要批量生成多个A记录的JSON,仅修改外层a.id的过滤规则即可,内层子查询会自动匹配对应AID的B/C数据,不会全量扫描。

内容的提问来源于stack exchange,提问作者f.khantsis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:24:04