Мне нужно прочитать каждую строку из сложного запроса в SQL серверной базе данных, используя Hibernate, и записать результат в файл. Но запрос может вернуть миллионы записей, поэтому казалось, что следующий код подходит:
Session unwrap = entityManager.unwrap(Session.class);
NativeQuery nativeQuery =
unwrap.createNativeQuery("the sql query string read from a file");
nativeQuery.setFlushMode(FlushMode.MANUAL);
nativeQuery.addEntity("C", CustomObject.class);
nativeQuery.setFetchSize(100000);
nativeQuery.setReadOnly(true);
ScrollableResults scroll = nativeQuery.scroll(ScrollMode.FORWARD_ONLY);
while(scroll.next()) {
CustomObject customObject = (CustomObject) scroll.get(0);
jsonGenerator.writeObject(customObject); // using the JsonGenerator library https://fasterxml.github.io/jackson-core/javadoc/2.6/com/fasterxml/jackson/core/JsonGenerator.html
unwrap.evict(claimEntity);
}
В настоящее время этот код занимает примерно 3-4 дня, чтобы записать в файл около 1 миллиона записей, что слишком медленный. Я использую драйвер ms sql -jdb c в режиме гибернации, и я предполагаю, что драйвер может игнорировать размер выборки, но мне не нужно менять драйвер, так как другие драйверы не поддерживают массовую копию функциональность.
Проблема в том, что hibernate, вероятно, устанавливает соединение для извлечения каждой строки отдельно от базы данных, что приводит к дорогостоящим сетевым вызовам.
Я попытался установить адаптивную буферизацию, включенные курсоры, установить соединение режим автоматической фиксации к false и другим вещам, но, кажется, ничто не могло сделать это быстрее.
Я хотел бы сделать это быстрее и был бы признателен за любую помощь.