如何加速非常大的集合的延迟加载

How to speed up lazy-Loading of very large collections

我的印象是,hibernate.default_batch_fetch_size 应该类似于在 jdbc-PreparedStatement 中设置批量大小。我的实验表明情况并非如此。如何强制 Hibernate 使用更大的 fetch-size?

我们有一个 spring/hibernate webapp 使用 Oracle RDBMS 来实现持久性。 我们最近遇到了一种情况,我们有一个 one-to-many 与“多”方超过一百万个条目的关联。

Hibernate 花了一分多钟才具体化集合。使用分析器进行的评估显示,hibernate 执行一个加载语句,并且在传输数据(而不是在 RDBMS 中准备数据)期间丢失了时间。有点可疑的是,探查器报告 大量 套接字读取导致非常小的数据包。另外,每个读包都有对应的写包。

我们尝试优化最初设置为 4 的 hibernate.default_batch_fetch_size。但是,增加到 10 甚至 100 会使执行速度变慢(从而证明,更改有 一些 影响)。减少到 1 也会减慢获取速度。在 Hibernate 中更改提取大小时,套接字包大小基本不受影响。

困惑 我尝试了一个简单的 Java 程序,它模仿了 hibernate 应该做的事情(即设置语句的批处理大小,通过反射构造结果对象)。根据批量大小,我得到的执行时间不到 1 秒。

Profiler 支持明显的结论:读取包的大小增长了十倍以上,而写入包的数量大幅减少。传输的数据总量大大减少:Hibernate 从套接字读取大约 56MB,plain JDBC 以小于 10MB 的大读取大小进行管理。减少 JDBC 端的获取大小使图片均衡。

问题:要让 Hibernate 使用 JDBC-Fetch 大小,我需要做什么?显然,简单地设置 hibernate.default_batch_fetch_size 是不够的。

编辑,结论

根据@TRW 的建议,可以加快加载速度。 Hibernate 仍然比普通 JDBC 慢很多,但我们得到了 3 倍的加速并且仍在尝试找出参数的最佳设置。

基于 question/answer What is the difference between hibernate.jdbc.fetch_size and hibernate.jdbc.batch_size? try to set the properties hibernate.jdbc.fetch_size and hibernate.jdbc.batch_size. At least the property 'hibernate.jdbc.fetch_size' sets the fetch size directly on the JDBC connection as you do in the JDBC test itself. See 4.5.4. Batching Database Operations.