APIJSON icon indicating copy to clipboard operation
APIJSON copied to clipboard

能否解决一下著名的N+1性能问题

Open StickChen opened this issue 3 years ago • 3 comments

问题描述 目前对于有一对多关系的关联查询,如下,会存在著名的N+1问题,这个在Hibernate、graphql中都是重点问题,希望能解决一下。

{
  "[]":{                             //请求一个数组
    "page":0,                        //数组条件
    "count":5,
    "Moment":{                       //请求一个名为Moment的对象
    },
    "User":{
      "id@":"/Moment/userId",        //User.id = Moment.userId  缺省引用赋值路径,从所处容器的父容器路径开始
    },
    "Comment[]":{                    //请求一个名为Comment的数组,并去除Comment包装
      "count":2,
      "Comment":{
        "momentId@":"[]/Moment/id"   //Comment.momentId = Moment.id  完整引用赋值路径
      }
    }
  }
}

这里查询Moment列表,带出User和CommentList时都是查询了N遍,希望能优化一下 目前通过app join可以解决一对一的情况,一对多还是不行的。

StickChen avatar Mar 21 '22 03:03 StickChen

这里和 Moment 写在同一层级的 User 可以用 APP JOIN/LEFT JOIN 优化 "join": "@/User/id@" // APP JOIN,两条 SQL,副表 User WHERE id IN(主表 Moment.userId 集合) "join": "</User/id@" // LEFT JOIN,一套 SQL,Moment LEFT JOIN User ON User.id = Moment.userId

https://github.com/Tencent/APIJSON/blob/master/Document.md#3.2

后续 APP JOIN 将支持跨层级,感谢建议~

TommyLemon avatar Mar 22 '22 14:03 TommyLemon

APIAuto 上有关于 APIJSON 各种零代码 JOIN 的例子 http://apijson.cn/api/ image

视频 https://www.bilibili.com/video/BV1LU4y157eP

TommyLemon avatar Mar 22 '22 14:03 TommyLemon

APP JOIN 文档: https://github.com/Tencent/APIJSON/blob/master/Document.md#32-%E5%8A%9F%E8%83%BD%E7%AC%A6 ECF00BA94339079C4233AE3CD1948D78

如果 APP JOIN 要支持一对多的写法,可以在 AbstractParser.onJoinParse 内判断 isAppJoin(join 值以 "@/" 开头),这种情况下允许写成 "@/ViceTable[]/ViceTable" 或 "@/ViceTable[]/ViceTable/key@" 这两种形式,相比原来仅支持的一对一写法 "@/ViceTable" 和 "@/ViceTable/key@",一对多中间多了数组名 ViceTable[]。 https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java#L1449-L1480 image

这个数量 1 目前是按一对一设置的,适配一对多需要在 AbstractParser.onJoinParse 把副表数组内的 count 取出来(没有就用默认值)存到 Join 内属性, https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java#L1576-L1649

C9222DE9038D8C61104B018BE9E5AD5F

然后这里给 cacheConfig 设置进去 https://github.com/Tencent/APIJSON/blob/master/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L5010-L5011 F969E2F1DFF390CB5F60B093570E49AB

可以先按以上方式验证 APP JOIN 是否能按一对多结构返回副表数据,且手动传参 count:1 时查副表数组应该走缓存。 此时副表数组内只返回一个值,没其它问题的话再改 setCount。

TommyLemon avatar Jun 09 '22 09:06 TommyLemon

@StickChen APIJSON 5.1.5 已支持跨层级 APP JOIN。

跨级 APP JOIN;腾讯业务百万数据 6s 响应 https://github.com/Tencent/APIJSON/releases/tag/5.1.5 image

目前最新版是 5.3.0。 APIJSON 5.3.0 支持达梦数据库,新进腾讯前 9 开源项目 https://www.oschina.net/news/214851/apijson-5-3-released

TommyLemon avatar Oct 31 '22 07:10 TommyLemon