我只需要使用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]);
以上问题是由于前文提到的代码会在进入while循环之前尝试将所有9000万行数据加载到内存中,这将导致OutOfMemoryError: Java heap space异常。那么,滚动结果集(ScrollableResults)似乎并不是我想要的解决方案。有什么适当的方法来处理这个问题吗?我不介意这个while循环花费几天时间(虽然确实不希望)。我猜另一种处理方法是使用setFirstResult和setMaxResults来遍历结果,并且使用普通的Hibernate结果而不是滚动结果集。不过,这样做可能效率低下,而且当我在第8900万行上调用setFirstResult时,它会开始花费非常长的时间......更新:setFirstResult/setMaxResults不可行,因为像我担心的那样,到达偏移量需要太长时间。必须有解决方法!难道这不是相当标准的程序吗?我愿意放弃Hibernate使用JDBC或任何必要的工具。更新2:我想到的解决办法能够运行但效果一般,基本上是这种形式:select * from person where id > <offset> and <other_conditions> limit 1
由于我有其他条件,即使都在一个索引中,仍然不如我希望的那么快...所以仍然需要其他建议...