【发布时间】:2021-03-31 23:11:55
【问题描述】:
我正在尝试提高应用程序的性能,所以我们做的第一件事就是查看数据库查询以优化它们。
我们做的一件事是在适当的地方添加“join fetch”和“left join fetch”以删除 N+1 个查询。
另一种方法是批量检索结果 (select distinct stuff from stuff left join fetch other_stuff where id in (?1)),而不是 for 循环逐个检索结果 (for (id: ids) select distinct stuff from stuff left join fetch other_stuff where id = ?1)。
问题在于,虽然我们的查询速度更快,数据库负载也更低,但似乎 hibernate 需要更多内存才能做到这一点。
在分析应用程序时,我可以看到每秒分配的对象数超过 500 000。垃圾收集器跟不上,应用程序冻结并最终导致 OutOfMemory。
从 hprof 来看,大多数对象似乎是在休眠类中分配的。最严重的违规者似乎是查询select where id in (?1) 的大部分内容。它每秒执行一次,检索大约 500 个对象,但似乎负责每秒大约 300 000 个对象分配。
我的猜测是,由于连接,数据库返回 300 000+ 行(这确实是我手动运行 select count(*) from stuff join other_stuff 时得到的),hibernate 必须在将所有内容合并到我最后的 500 个对象中之前全部分配。
我说的对吗?
我想不执行 left join fetch 并让休眠使用单独的查询加载它们会大大减少分配,但会损害性能。
有没有办法在立即获取的同时减少内存分配?
谢谢
【问题讨论】:
标签: java hibernate join memory