【发布时间】:2011-02-19 01:23:55
【问题描述】:
我只需要使用 Hibernate 读取 MySQL 数据库中表中的每一行并基于它编写一个文件。但是有 9000 万行,而且非常大。因此,以下内容似乎是合适的:
ScrollableResults results = session.createQuery("SELECT person FROM Person person")
.setReadOnly(true).setCacheable(false).scroll(ScrollMode.FORWARD_ONLY);
while (results.next())
storeInFile(results.get()[0]);
问题是上面将尝试将所有 9000 万行加载到 RAM 中,然后再进入 while 循环......这会用 OutOfMemoryError: Java heap space exceptions 杀死我的内存:(。
所以我猜 ScrollableResults 不是我想要的?处理这个问题的正确方法是什么?我不介意这个 while 循环是否需要几天时间(我不希望这样)。
我想处理这个问题的唯一其他方法是使用 setFirstResult 和 setMaxResults 来遍历结果,并且只使用常规的 Hibernate 结果而不是 ScrollableResults。不过,这感觉效率很低,当我在第 89 百万行调用 setFirstResult 时,它会开始花费相当长的时间......
更新:setFirstResult/setMaxResults 不起作用,结果需要很长时间才能达到我担心的偏移量。这里一定有解决办法!这不是一个非常标准的程序吗?我愿意放弃 Hibernate 并使用 JDBC 或任何它需要的东西。
更新 2:我想出的解决方案可以正常工作,但不是很好,基本上是以下形式:
select * from person where id > <offset> and <other_conditions> limit 1
由于我有其他条件,即使所有条件都在索引中,它仍然没有我希望的那么快......所以仍然欢迎其他建议..
【问题讨论】:
-
您也许可以对数据进行分区,这样您就不必一次读取那么多,参考:stackoverflow.com/questions/8325745/…
标签: java mysql hibernate large-data-volumes scrollableresults