【问题标题】:Bulk loading of data with libpqxx使用 libpqxx 批量加载数据
【发布时间】:2011-06-07 08:57:24
【问题描述】:

我需要使用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 不会复制任何外键约束,所以我似乎也需要手动指定这些约束。或者有没有办法将这些与所有其他约束一起处理?

【问题讨论】:

    标签: c++ postgresql libpqxx


    【解决方案1】:

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

    您可以使用线程安全队列或使用 PostgreSQL NOTIFY 等方式将数据发送到应用程序内部的索引线程。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-25
          • 1970-01-01
          • 2015-01-15
          • 1970-01-01
          • 2020-11-17
          • 2018-08-18
          相关资源
          最近更新 更多