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

[Bug]在多层级with情况下使用出现代码运行缓慢的问题 #46

Open
zc269105964 opened this issue Feb 25, 2025 · 12 comments
Open
Labels
bug Something isn't working

Comments

@zc269105964
Copy link

1.使用的代码库的方式 ? maven依赖

2.使用的代码库的版本 ? 5.5.3

3.java版本 23

4.框架以及版本 spring boot 3.4.0

5.数据库以及版本 mysql 5.8

6.问题简述 ( 有必要的话, 可以贴下相关调用代码以及定义代码 )
model.newQuery().with("a.b.c.d").paginate(1, 15) 运行了 3 秒,但是 sql 执行时间不超过 0.3 秒,排查发现RelationGetSupport.toObjectList 方法多次调用,model 查询出15条数据,model->a 一对多17条数据,a->b一对一16 条数据,b->c一对多1条数据,c->d一对一1条数据,该方法调用18W+次,里面还嵌套了遍历,导致代码遍历次数过多
7.预期效果
优化 RelationGetSupport.toObjectList 方法调用次数

@zc269105964 zc269105964 added the bug Something isn't working label Feb 25, 2025
@xutengx
Copy link
Member

xutengx commented Feb 26, 2025

你好, 这边发现的确存在对 RelationGetSupport.toObjectList 的重复调用的情况.

等我消息.

@zc269105964
Copy link
Author

大佬,还有一个小问题,看能否顺便一起优化下
studentModel.newQuery().with("teacher", builder -> builder.select("column1", "column2")).get().toObject();
期望关联查询teacher时,只查询 column1、column2 字段
但是实际 sql 查询了所有字段,且查询字段里 column1、column2 会重复

@xutengx
Copy link
Member

xutengx commented Feb 27, 2025

你好, 5.5.4 有优化以上2点
关于第一点, 对于我的测试案例里面, 调用耗时的优化大概是 500ms 到 400ms 的幅度.
可以先试用下, 看下对于你代码环境中的实际使用效果, 期待你的反馈.

@zc269105964
Copy link
Author

你好, 5.5.4 有优化以上2点 关于第一点, 对于我的测试案例里面, 调用耗时的优化大概是 500ms 到 400ms 的幅度. 可以先试用下, 看下对于你代码环境中的实际使用效果, 期待你的反馈.

Image

Image

Image

Image

我试了下关联三个,5.5.3大概12秒、5.5.4大概8秒;

@zc269105964
Copy link
Author

关联4个,5.5.3 2分40秒,5.5.4 1分55秒
感觉是不是哪里还有多层遍历啊??

@zc269105964
Copy link
Author

Image

Image

Image

发现一个奇怪的问题,因为我们项目软删字段逻辑不一致,我们把5.5.4代码改了软删部分的源码,重新打包后引入 database-query-mysql 本地 jar 包,加了 orderBy 的情况下,代码运行时间相差甚大

@xutengx
Copy link
Member

xutengx commented Feb 28, 2025

你好, 5.5.5 有提升

发现一个奇怪的问题,因为我们项目软删字段逻辑不一致,我们把5.5.4代码改了软删部分的源码,重新打包后引入 database-query-mysql 本地 jar 包,加了 orderBy 的情况下,代码运行时间相差甚大

是指的存在 orderBy的情况情况下, 变慢了很多 ( 可能是覆盖了软删除相关的代码的原因 )的情况对吗 ?

根据你的代码, 在项目中的模型基类 eg : BaseModel 中重写相关的方法应该可以方便的实现 ( 软删除的逻辑变更 ) 呀

@zc269105964
Copy link
Author

zc269105964 commented Feb 28, 2025

你好, 5.5.5 有提升

发现一个奇怪的问题,因为我们项目软删字段逻辑不一致,我们把5.5.4代码改了软删部分的源码,重新打包后引入 database-query-mysql 本地 jar 包,加了 orderBy 的情况下,代码运行时间相差甚大

是指的存在 orderBy的情况情况下, 变慢了很多 ( 可能是覆盖了软删除相关的代码的原因 )的情况对吗 ?

根据你的代码, 在项目中的模型基类 eg : BaseModel 中重写相关的方法应该可以方便的实现 ( 软删除的逻辑变更 ) 呀

Image

Image

好的,等会我试下 5.5.5
改源码主要是以下两个原因:
1.在BelongsToManyQueryRelation、BelongsToQueryRelation、HasOneOrManyQuery中要获取到对应的 Template 类中类属性;
2.项目有多个数据库连接,BaseModel 中,重写了 getTableName 方法,统一拼接上了 connection 名称,后面发现with查询时,关联表表名和字段名一起加上了 ` ,所以修改了 RelationFormatUtils.backQuote 中字段拼接 的逻辑
这两个好像无法通过重写实现

@xutengx
Copy link
Member

xutengx commented Feb 28, 2025

提及的2个原因, 似乎有机会, 通过不改写源码实现, 以下供参考

1.在BelongsToManyQueryRelation、BelongsToQueryRelation、HasOneOrManyQuery中要获取到对应的 Template 类中类属性;

参考 自定义关系, 使用自定义的注解, 就可以指定自定义的解析器, 那么这个自定义的解析器自然就为所欲为啦.

2.项目有多个数据库连接,BaseModel 中,重写了 getTableName 方法,统一拼接上了 connection 名称,后面发现with查询时,关联表表名和字段名一起加上了 ` ,所以修改了 RelationFormatUtils.backQuote 中字段拼接 的逻辑

参考 自定义查询构造器Query方法, 其中自定义的查询构造器 ( eg : MySqlBuilderV2 ) 中的 backQuote 方法使用你的逻辑, 当然其他的方法 ( eg : from ) 都可以进行任意改动.

@zc269105964
Copy link
Author

提及的2个原因, 似乎有机会, 通过不改写源码实现, 以下供参考

1.在BelongsToManyQueryRelation、BelongsToQueryRelation、HasOneOrManyQuery中要获取到对应的 Template 类中类属性;

参考 自定义关系, 使用自定义的注解, 就可以指定自定义的解析器, 那么这个自定义的解析器自然就为所欲为啦.

2.项目有多个数据库连接,BaseModel 中,重写了 getTableName 方法,统一拼接上了 connection 名称,后面发现with查询时,关联表表名和字段名一起加上了 ` ,所以修改了 RelationFormatUtils.backQuote 中字段拼接 的逻辑

参考 自定义查询构造器Query方法, 其中自定义的查询构造器 ( eg : MySqlBuilderV2 ) 中的 backQuote 方法使用你的逻辑, 当然其他的方法 ( eg : from ) 都可以进行任意改动.

我只是想获取到 BelongsToQueryRelation 类中类 belongsToTemplate 的属性,通过自定义关系,那岂不是要把BelongsToQueryRelation的所有代码都复制到我自定义的类文件中??

@xutengx
Copy link
Member

xutengx commented Feb 28, 2025

5.5.7
关联关系相关实现类HasOneOrManyQueryRelation,BelongsToQueryRelation,BelongsToManyQueryRelation更改可见性, 是其更易被继承

@zc269105964
Copy link
Author

提及的2个原因, 似乎有机会, 通过不改写源码实现, 以下供参考

1.在BelongsToManyQueryRelation、BelongsToQueryRelation、HasOneOrManyQuery中要获取到对应的 Template 类中类属性;

参考 自定义关系, 使用自定义的注解, 就可以指定自定义的解析器, 那么这个自定义的解析器自然就为所欲为啦.

2.项目有多个数据库连接,BaseModel 中,重写了 getTableName 方法,统一拼接上了 connection 名称,后面发现with查询时,关联表表名和字段名一起加上了 ` ,所以修改了 RelationFormatUtils.backQuote 中字段拼接 的逻辑

参考 自定义查询构造器Query方法, 其中自定义的查询构造器 ( eg : MySqlBuilderV2 ) 中的 backQuote 方法使用你的逻辑, 当然其他的方法 ( eg : from ) 都可以进行任意改动.

还有一个问题,通过自定义查询构造器Query方法,好像没有办法新增方法,只能重写原 builder 的方法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants