首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用libpqxx进行大容量存储数据或如何在libpqxx中使用COPY语句

使用libpqxx进行大容量存储数据或如何在libpqxx中使用COPY语句
EN

Stack Overflow用户
提问于 2013-10-30 13:51:49
回答 1查看 2.3K关注 0票数 3

要在PostgreSQL中插入大容量数据/填充数据库,最快的方法是使用复制。来源

我必须填充一个数据库。现在,我得到的写速度低到100-200每秒.这涉及到通过C++库libpqxx发送许多单独的插入。我认为有两个原因:

  1. 数据有许多重复的记录.(我有原始日志,我解析和发送这些日志)。这将导致主键异常。
  2. 逐个发送Insert语句.

第一个是我无法控制的。然而,我读到了关于第二篇文章的文章。

据我所知,制表类适合这一目的。然而,它显然遭到了反对。我读过,可以使用stdin作为复制的参数。

但在这些线索之后我迷失了方向。有人能帮我找到解决方案吗?

编辑:下面是代码,其中有一个执行状态的函数:

代码语言:javascript
复制
void pushLog(Log log,pqxx::connection *conn){
    pqxx::work w(*conn);
    std::stringstream stmt;
    stmt<<"INSERT INTO logs VALUES('"<<log.getDevice()<<"','"<<log.getUser()<<"','"<<log.getDate()<<"','"<<log.getLabel()<<"');";
    try{
        pqxx::result res = w.exec(stmt.str());
        w.commit();
    }
    catch(const std::exception &e){
        std::cerr << e.what() << std::endl;
        std::cout<<"Exception on statement:["<<stmt.str()<<"]\n";
        return;
    }

}

我更早地建立了连接,并传递了对它的引用。

PS:这个问题可能缺乏一些细节。如果是,请评论,我将编辑和添加他们。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-30 18:19:44

pushLog函数分别提交每个插入,而且提交速度很慢。

正如文档的填充数据库所解释的那样

如果允许单独提交每个插入,则PostgreSQL将对所添加的每一行进行大量工作。

另外:

在一个事务中执行所有插入的另一个好处是,如果插入一行失败,那么插入到该点的所有行的插入都会回滚,因此您不会被部分加载的数据困住。

但是,在您的情况下,这将是一个问题,而不是一个好处,因为每次插入都可能在主键冲突时失败,从而取消了上次提交后的先前插入。请注意,如果您使用COPY,这也是一个问题。

由于确实有必要对事务中的查询进行分组以提高性能,因此您需要以一种不中止事务的方式处理主键冲突。

通常使用两种方法:

  1. 避免错误:INSERT INTO... WHERE NOT EXISTS (SELECT 1 FROM table WHERE primary_key=...)
  2. 通过插入具有异常块的plpgsql函数来捕获错误,忽略它。导致重复的特定插入将被取消,但事务不会被中止。

如果您有并发插入,则需要使用锁定策略对这些方法进行细化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19684168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档