使用libpqxx批量加载数据

时间:2011-06-07 08:57:25

标签: c++ postgresql libpqxx

我需要使用libpqxx将大量数据(大约7.000.000个条目)批量加载到PostgreSQL数据库中。我已阅读how to populate the database上的文档,但我不确定如何在我的情况下使用它。首先我不能使用文件,因此数据库上的COPY是不可能的。此外,我正在加载的数据库和表需要在导入时正常运行。

方案如下:我们定期(大约每月一次)从另一个应用程序获取包含所有数据(包括已存在的条目)的文件。由于条目数量的原因,无法检查每个条目是否存在,我们只是大量插入新数据(在预处理之后)。

目前为了处理这个问题,我创建了一个新表,使用libpqxx中的tablewriter插入数据(没有事务)然后在事务中我将旧表重命名并将新表重命名到正确的位置。

此外,我们不仅需要为一个表执行此操作,而且需要为具有不同布局的多个表执行此操作。因此,我试图将表的写入与日期的解析分开。现在我只需要分解表的创建。为此,我使用了

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

这样我得到一张类似于foo的表格,我不需要在我写作的地方真正了解布局。然而,这给我留下了问题,这将产生一个包含索引和约束的表,上面的指南说索引会使批量插入变慢。但是,如果我删除索引和约束(或者不首先复制它们),我需要一种方法,然后在为原始表设置的相同庄园中重新创建它们。

关于如何快速处理这个问题的任何好的提示?

编辑:

在相关方面:玩我刚才注意到的数据库,上面的CREATE TABLE不会复制任何外键约束,所以我似乎也需要手动指定这些。或者有没有办法与所有其他约束一起处理这些?

3 个答案:

答案 0 :(得分:2)

我使用下一个策略创建索引和约束,每秒实现超过100000次插入: 1.在第一个连接中创建表,该表继承父,使用PQputCopyData以二进制模式复制数据。 2.使用其他几个连接来创建索引。 PostgreSQL为每个客户端创建一个线程,因此为了使用多核优势,我们需要使用多个连接。

您可以使用类似线程的队列或使用PostgreSQL NOTIFY将数据发送到应用程序内的索引线程。

答案 1 :(得分:1)

有一个pg_index和pg_constraint表,它们引用索引和约束。 (前者需要与pg_class联接才能获得完整的详细信息。)有关血淋淋的详细信息,请参阅pg_catalog

您可以使用后者在批量插入/更新后获取所需的索引定义等。

答案 2 :(得分:1)

您不需要外部文件即可使用COPY。您可以从“STDIN”复制。 “STDIN指定输入来自客户端应用程序。”

例如,使用pg_dumpall,它将向您展示如何在现有数据中使用/格式化COPY。

您可以使用PQputCopyData将必要的批量数据传输到PostgreSQL服务器。

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