Мне нужно программно вставить десятки миллионов записей в базу данных postgres. В настоящее время я выполняю тысячи операторов вставки в одном «запросе».
Есть ли лучший способ сделать это, какое-то массовое выражение вставки, о котором я не знаю?
postgresql
bulkinsert
ясень
источник
источник
Существует альтернатива использованию COPY - синтаксис многострочных значений, поддерживаемый Postgres. Из документации :
Приведенный выше код вставляет две строки, но вы можете расширять его произвольно, пока не достигнете максимального количества подготовленных токенов операторов (это может быть 999 долларов, но я не уверен на 100% в этом). Иногда нельзя использовать COPY, и это достойная замена для таких ситуаций.
источник
Одним из способов ускорить процесс является явное выполнение нескольких вставок или копий в транзакции (скажем, 1000). Поведение Postgres по умолчанию заключается в фиксации после каждого оператора, поэтому, пакетируя коммиты, вы можете избежать некоторых накладных расходов. Как говорится в ответе Даниэля, возможно, вам придется отключить автокоммит, чтобы это работало. Также обратите внимание на комментарий внизу, который предлагает увеличить размер wal_buffers до 16 МБ, также может помочь.
источник
UNNEST
Функция с массивами может использоваться вместе с многорядным синтаксисом VALUES. Я думаю, что этот метод медленнее, чем использование,COPY
но он полезен для меня при работе с psycopg и python (pythonlist
передается вcursor.execute
pgARRAY
):без
VALUES
использования подвыбора с дополнительной проверкой существования:тот же синтаксис для массовых обновлений:
источник
Вы можете использовать,
COPY table TO ... WITH BINARY
что « несколько быстрее, чем текст и форматы CSV ». Делайте это только в том случае, если у вас есть миллионы строк для вставки и если вы знакомы с двоичными данными.Вот пример рецепта в Python, использующего psycopg2 с двоичным вводом .
источник
В основном это зависит от (другой) активности в базе данных. Такие операции эффективно замораживают всю базу данных для других сеансов. Другое соображение - это модель данных и наличие ограничений, триггеров и т. Д.
Мой первый подход всегда: создать (временную) таблицу со структурой, аналогичной целевой таблице (создать таблицу tmp AS select * from target, где 1 = 0), и начать с чтения файла во временную таблицу. Затем я проверяю, что можно проверить: дубликаты, ключи, которые уже существуют в цели, и т. Д.
Затем я просто делаю «сделать вставку в целевой select * from tmp» или подобное.
Если это не удается или занимает слишком много времени, я прекращаю его и рассматриваю другие методы (временное удаление индексов / ограничений и т. Д.)
источник
Я реализовал очень быстрый загрузчик данных Postgresq с помощью собственных методов libpq. Попробуйте мой пакет https://www.nuget.org/packages/NpgsqlBulkCopy/
источник
Я только что столкнулся с этой проблемой и рекомендую csvsql ( релизы ) для массового импорта в Postgres. Чтобы выполнить массовую вставку, вы просто
createdb
и затем используете ееcsvsql
, которая подключается к вашей базе данных и создает отдельные таблицы для всей папки CSV.источник
Внешний файл - это лучшие и типичные объемные данные.
Термин «объемные данные» относится к «большому количеству данных», поэтому естественно использовать исходные необработанные данные без необходимости их преобразования в SQL. Типичными файлами необработанных данных для «массовой вставки» являются форматы CSV и JSON .
Массовая вставка с некоторым преобразованием
В приложениях ETL и процессах приема данных нам нужно изменить данные перед их вставкой. Временная таблица потребляет (много) дискового пространства, и это не быстрый способ сделать это. Обертка внешних данных PostgreSQL (ИДП) является лучшим выбором.
CSV пример . Предположим , что
tablename (x, y, z)
на SQL и CSV файл , какВы можете использовать классический SQL
COPY
для загрузки ( как и исходные данные), в которыйtmp_tablename
они вставляют отфильтрованные данныеtablename
... Но, чтобы избежать потребления диска, лучше всего проглотить непосредственноВам нужно подготовить базу данных для FDW, и вместо статической
tmp_tablename_fdw
вы можете использовать функцию, которая ее генерирует :Пример JSON . Набор из двух файлов,
myRawData1.json
иRanger_Policies2.json
может поступать в организм с помощью:где функция jsonb_read_files () читает все файлы папки, определенные маской:
Отсутствие потоковой передачи gzip
Наиболее частый метод «загрузки файлов» (главным образом в больших данных) - это сохранение исходного файла в формате gzip и передача его с помощью потокового алгоритма , всего, что может работать быстро и без использования диска в каналах Unix:
Таким образом, идеальный (будущий) вариант сервера для формата
.csv.gz
.источник