Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
StickChen opened this issue Mar 21, 2022 · 4 comments
Closed

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

StickChen opened this issue Mar 21, 2022 · 4 comments
Labels

Comments

@StickChen
Copy link

问题描述
目前对于有一对多关系的关联查询,如下,会存在著名的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可以解决一对一的情况,一对多还是不行的。

@TommyLemon
Copy link
Collaborator

TommyLemon commented Mar 22, 2022

这里和 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 TommyLemon added the Enhancement 增强 增强功能、提高性能等 label Mar 22, 2022
@TommyLemon
Copy link
Collaborator

TommyLemon commented Mar 22, 2022

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

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

@TommyLemon
Copy link
Collaborator

TommyLemon commented Jun 9, 2022

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
Copy link
Collaborator

TommyLemon commented Oct 31, 2022

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants