См. Заполнение базы данных в руководстве по 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вместо INSERTs
Если вы не можете использовать, COPYрассмотрите возможность использования многозначных INSERTs, если это возможно. Вы, кажется, уже делаете это. Не пытайтесь перечислить слишком много значений в одном 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 для быстрого тестирования .