LINUX.ORG.RU

Оптимизация INSERT-запросов в PostgreSQL

 , , ,


2

2

День добрый сообществу.

Имеется база данных PostgreSQL и код на Java, который пишет в большом количестве INSERTы в таблицу. В данный момент работа с БД выполняется напрямую через JDBC. То есть, я формирую строку-запроса и отправляю ее на драйвер, обрабатываю результат и ошибки. Когда много запросов, я объединяю их в длинную строку и затем отправляю. Проблема в том, что данная работа со строками сжирает жутко много времени и в итоге я получаю дикие тормоза при работе с такими INSERTами.

При объединении 30-50 запросов в одну строку действительно получилось ускорить процесс, однако все равно занимает слишком много времени. Я подозреваю, что можно существенно ускорить процесс.

Поможет ли мне Hibernate? Сумеет ли он гораздо быстрее выполнять такие запросы? Могу ли я только некоторые задачи перенести на него, а все остальное оставить работающим напрямую через драйвер?

Быть может мне попробовать формировать дампы и их затем выливать в БД?

Индексы в данной ситуации мне не помогут.

Лоровец, как еще максимально быстро я могу записать много информации в БД? Спасибо.

А в транзакцию обернуть?

Индексы в данной ситуации мне не помогут.

Они только тормозят INSERT.

crowbar ()
Ответ на: комментарий от crowbar

А в транзакцию обернуть?

Сконкатенировать строки запросов в одну? Я так делаю, мало эффекта.

Или ты о чем-то другом?

observer ★★★ ()

COPY ускоряет в сотни раз при вставке нескольких тысяч записей. Текстовые дампы в pg_dump так и делаются

disarmer ★★★ ()

Маленькое улучшение, которое тебе даст большую прибавку в скорости - prepared statements + batch updates. Если очень много данных заливаешь - разбивай на несколько транзакций. С потолка цифры - шли батчи по 100 insert-ов каждый и оборачивай в транзакцию по 1000 insert-ов каждая.

Самый быстрый способ для заливки данных это подготовить файл с данными в специальном формате (например CSV), залить его на сервер с БД и специальной командой залить его в БД. Понятно, что переписывать придётся вообще всё и способ довольно неудобный для использования.

Hibernate тебе не поможет никак.

Ещё может помочь отключение индексов и прочих проверок на используемые таблицы перед заливкой (и включение после заливки, естественно).

Legioner ★★★★★ ()

про batch update должен узнать ты.

maloi ★★★★★ ()

Всем спасибо, COPY помогло.

Будет время, еще гляну о batch update.

observer ★★★ ()

Через хибер проще всего с помощью StatelessSession. Вставляй все это дело в транзакции, каждые N записаей делаей flush.

dizza ★★★★★ ()
Ответ на: комментарий от maxcom

можно еще выставить

synchronous_commit=off
.

Еще можно выкрутить

commit_delay
что бы fsync был пореже или вообще его отключить если автор понимает что он делает.

Еще можно

checkpoint_segments
поднять и включить
log_checkpoints
.

Но в любом случае стоит понимать что все эти техники могут привести к превращению данных в тыкву.

catap ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.