Мне просто нужно прочитать каждую строку в таблице в моей базе данных 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-миллионной строке...
UPDATE: setFirstResult/setMaxResults не работает, получается, что требуется слишком много времени, чтобы добраться до смещений, как я боялся. Здесь должно быть решение! Разве это не стандартная процедура? Я готов отказаться от Hibernate и использовать JDBC или что-то еще, что нужно.
ОБНОВЛЕНИЕ 2: решение, которое я придумал, работает нормально, а не отлично, в основном имеет форму:
select * from person where id > <offset> and <other_conditions> limit 1
Поскольку у меня есть другие условия, даже все в индексе, это все еще не так быстро, как хотелось бы... так что все еще открыта для других предложений.