Мне просто нужно прочитать каждую строку в таблице в моей базе данных MySQL, используя Hibernate, и записать файл на ее основе. Но есть 90 миллионов строк, и они довольно большие. Таким образом, казалось, что было бы целесообразно следующее:
ScrollableResults results = session.createQuery("SELECT person FROM Person person")
.setReadOnly(true).setCacheable(false).scroll(ScrollMode.FORWARD_ONLY);
while (results.next())
storeInFile(results.get()[0]);
Проблема в том, что описанное выше попытается загрузить все 90 миллионов строк в ОЗУ, прежде чем перейти к циклу while ... и это уничтожит мою память с помощью OutOfMemoryError: исключения пространства кучи Java: (..
Итак, я думаю, ScrollableResults - это не то, что я искал? Как правильно справиться с этим? Я не против, если этот цикл занимает дни (ну, я бы с удовольствием это сделал).
Полагаю, единственный другой способ справиться с этим - использовать setFirstResult и setMaxResults для перебора результатов и просто использовать обычные результаты Hibernate вместо ScrollableResults. Такое ощущение, что это будет неэффективно, и начнёт занимать смехотворно много времени, когда я вызову setFirstResult для 89-миллионной строки ...
ОБНОВЛЕНИЕ: setFirstResult / setMaxResults не работает, оказывается, что до смещения, как я боялся, уходит необычайно много времени. Здесь должно быть решение! Разве это не довольно стандартная процедура? Я готов отказаться от Hibernate и использовать JDBC или что-то еще.
ОБНОВЛЕНИЕ 2: предложенное мной решение, которое работает нормально, не очень, в основном имеет вид:
select * from person where id > <offset> and <other_conditions> limit 1
Поскольку у меня есть другие условия, даже все в индексе, это все еще не так быстро, как хотелось бы ... так что все еще открыты для других предложений ..