Массовая загрузка данных с помощью libpqxx - PullRequest
3 голосов
/ 07 июня 2011

Мне нужно массово загрузить большой объем данных (около 7.000.000 записей) в базу данных PostgreSQL, используя libpqxx .Я прочитал документацию по как заполнить базу данных , но я не уверен, как использовать это в моем случае.Сначала я не могу использовать файлы, поэтому вопрос о COPY в базе данных не подлежит обсуждению.Кроме того, база данных и таблица, в которую я загружаю файлы, должны быть функциональными во время импорта.

Сценарий таков: мы получаем файл со всеми данными (включая уже имеющиеся записи) из другого приложения по адресурегулярные интервалы (примерно раз в месяц).Из-за количества записей просто невозможно проверить каждую запись на наличие, и мы просто выполняем массовую вставку новых данных (после предварительной обработки).

В настоящее время для обработки этого я создаю новую таблицу,вставьте данные, используя программу для записи таблиц из libpqxx (без транзакции), затем в транзакции я переименую старую таблицу и новую таблицу в правильное место.

Кроме того, нам нужно сделать это не только для одной таблицы,но для нескольких таблиц с разным расположением.Таким образом, я попытался отделить написание таблицы от анализа даты.Теперь мне просто нужно учесть создание таблицы.Для этого я использую

create temporary table foo_temp (like foo including indexes including defaults including constraints );

Таким образом, я получаю таблицу, похожую на foo, и мне не нужно фактически знать расположение в месте, где я пишу.Однако это оставляет меня с проблемой, что это приведет к созданию таблицы с индексами и ограничениями, а в приведенном выше руководстве сказано, что индексы замедляют массовую вставку.Однако, если я отбрасываю индексы и ограничения (или не копирую их в первую очередь), мне нужен способ воссоздать их впоследствии в том же поместье, в котором они были установлены для исходной таблицы.

Любые полезные советы о том, какчтобы справиться с этим быстро?

РЕДАКТИРОВАТЬ:

С другой стороны: Играя с базой данных Я только что заметил, что CREATE TABLE выше не будет копировать какие-либо ограничения внешнего ключа,так что, кажется, мне нужно указать их вручную.Или есть способ справиться с ними вместе со всеми другими ограничениями?

Ответы [ 3 ]

2 голосов
/ 21 августа 2011

Я достигаю более 100000 операций вставки в секунду при индексировании и создании ограничений, используя следующую стратегию: 1. При первом соединении создайте таблицу, которая наследует родительский объект, скопируйте данные в двоичном режиме, используя PQputCopyData.2. Используйте несколько других соединений для создания индекса.PostgreSQL создает один поток для каждого клиента, поэтому для использования преимуществ многоядерности нам нужно использовать несколько соединений.

Вы можете отправлять данные в индексирующие потоки внутри приложения, используя что-то вроде поточно-ориентированной очереди или используя PostgreSQL NOTIFY.

1 голос
/ 08 июня 2011

Вам не нужны внешние файлы, чтобы использовать COPY. Вы можете скопировать из "STDIN". "STDIN Указывает, что входные данные поступают от клиентского приложения."

Например, используйте pg_dumpall, который покажет вам, как использовать / форматировать COPY с вашими существующими данными.

Вы можете использовать PQputCopyData для передачи необходимых массовых данных на сервер PostgreSQL.

http://www.postgresql.org/docs/9.0/interactive/libpq-copy.html#LIBPQ-COPY-SEND

1 голос
/ 08 июня 2011

Существуют таблицы pg_index и pg_constraint, которые ссылаются на индексы и ограничения.(Первому требуется соединение с pg_class, чтобы получить полную информацию.) Подробную информацию смотрите в pg_catalog .

Вы можете использовать второе для получения необходимых определений индекса и так далее послеМассовые вставки / обновления.

...