См. Заполнение базы данных в руководстве по PostgreSQL, отличную, как обычно, статью Depesz по этой теме, и этот ТАК вопрос .
(Обратите внимание, что этот ответ касается массовой загрузки данных в существующую БД или создания новой. Если вы заинтересованы в восстановлении производительности БД с помощью pg_restore
или psql
выполнении pg_dump
вывода, большая часть этого не применяется с тех пор, pg_dump
и pg_restore
уже выполняет такие вещи, как создание триггеры и индексы после завершения схемы + восстановление данных) .
Есть много чего сделать. Идеальным решением было бы импортировать в UNLOGGED
таблицу без индексов, а затем изменить его на logged и добавить индексы. К сожалению, в PostgreSQL 9.4 нет поддержки смены таблиц с UNLOGGED
зарегистрированных. 9,5 добавляет, ALTER TABLE ... SET LOGGED
чтобы позволить вам сделать это.
Если вы можете перевести свою базу данных в автономный режим для массового импорта, используйте pg_bulkload
.
В противном случае:
Отключить любые триггеры на столе
Удалите индексы перед началом импорта, затем создайте их заново. ( Построение индекса за один проход занимает гораздо меньше времени, чем постепенное добавление к нему тех же данных, и полученный индекс намного более компактен).
Если вы выполняете импорт в пределах одной транзакции, можно безопасно удалить ограничения внешнего ключа, выполнить импорт и заново создать ограничения перед фиксацией. Не делайте этого, если импорт разбит на несколько транзакций, так как вы можете ввести неверные данные.
Если возможно, используйте COPY
вместо INSERT
s
Если вы не можете использовать, COPY
рассмотрите возможность использования многозначных INSERT
s, если это возможно. Вы, кажется, уже делаете это. Не пытайтесь перечислить слишком много значений в одном VALUES
; эти значения должны уместиться в памяти пару раз, так что держите их на несколько сотен на оператор.
Пакетные вставки в явные транзакции, делая сотни тысяч или миллионы вставок за транзакцию. Практического ограничения AFAIK нет, но пакетирование позволит вам восстановиться после ошибки, отметив начало каждого пакета в ваших входных данных. Опять же, вы, кажется, уже делаете это.
Используйте synchronous_commit=off
и огромное, commit_delay
чтобы уменьшить затраты fsync (). Это не сильно поможет, если вы сгруппировали свою работу в большие транзакции.
INSERT
или COPY
параллельно из нескольких соединений. Сколько зависит от дисковой подсистемы вашего оборудования; как правило, вам нужно одно соединение на физический жесткий диск, если используется хранилище с прямым подключением.
Установите высокое checkpoint_segments
значение и включитеlog_checkpoints
. Посмотрите журналы PostgreSQL и убедитесь, что они не жалуются на слишком часто возникающие контрольные точки.
Если и только если вы не против потерять весь ваш кластер PostgreSQL (вашу базу данных и все остальные в одном кластере) из-за катастрофического повреждения, если система потерпит крах во время импорта, вы можете остановить Pg, установить fsync=off
, запустить Pg, выполнить импорт, затем (жизненно) остановите Pg и установите fsync=on
снова. Смотрите конфигурацию WAL . Не делайте этого, если в какой-либо базе данных вашей установки PostgreSQL уже есть данные, которые вас интересуют. Если вы установите, fsync=off
вы также можете установить full_page_writes=off
; опять же, просто не забудьте включить его после импорта, чтобы предотвратить повреждение базы данных и потерю данных. Смотрите недолговечные настройки в руководстве по Pg.
Вы также должны посмотреть на настройку вашей системы:
Максимально используйте твердотельные накопители хорошего качества для хранения. Хорошие твердотельные накопители с надежным, защищенным питанием кэшем обратной записи делают скорость фиксации невероятно высокой. Они менее полезны, когда вы следуете совету, который приведен выше - что уменьшает количество дисковых сбросов / количество fsync()
секунд - но все же может помочь. Не используйте дешевые SSD без надлежащей защиты от сбоя питания, если только вы не заботитесь о сохранности своих данных.
Если вы используете RAID 5 или RAID 6 для хранилища с прямым подключением, остановитесь сейчас. Создайте резервную копию данных, реструктурируйте массив RAID в RAID 10 и попробуйте снова. RAID 5/6 безнадежен для массовой записи - хотя хороший RAID-контроллер с большим кешем может помочь.
Если у вас есть возможность использовать аппаратный RAID-контроллер с большим резервным кэшем с резервным питанием от батареи, это действительно может улучшить производительность записи для рабочих нагрузок с большим количеством коммитов. Это не очень помогает, если вы используете async commit с commit_delay или если вы делаете меньше больших транзакций во время массовой загрузки.
Если возможно, сохраните WAL ( pg_xlog
) на отдельном диске / массиве дисков. Нет смысла использовать отдельную файловую систему на одном диске. Люди часто предпочитают использовать пару RAID1 для WAL. Опять же, это больше влияет на системы с высокой частотой фиксации и мало влияет на то, что в качестве цели загрузки данных вы используете незафиксированную таблицу.
Вы также можете быть заинтересованы в Оптимизации PostgreSQL для быстрого тестирования .