Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用libpqxx批量存储数据或如何在libpqxx中使用COPY语句_C++_Mysql_Sql_Postgresql_Libpqxx - Fatal编程技术网

C++ 使用libpqxx批量存储数据或如何在libpqxx中使用COPY语句

C++ 使用libpqxx批量存储数据或如何在libpqxx中使用COPY语句,c++,mysql,sql,postgresql,libpqxx,C++,Mysql,Sql,Postgresql,Libpqxx,要在PostgreSQL中插入批量数据/填充数据库,最快的方法是使用COPY。 我必须填充一个数据库。现在我的写入速度低至每秒100-200。这涉及通过C++库LIPBQXX发送许多单独的插入。我想有两个原因: 数据有许多重复记录,我有原始日志,我解析并发送这些日志。这会导致主键异常。 逐个发送Insert语句。 第一个是我无法控制的。但是我读到了第二本。 据我所知,tablewriter类适合这个目的。然而,它显然遭到了反对。我已经了解到可以使用stdin作为参数进行复制。 但在这些线索之后,

要在PostgreSQL中插入批量数据/填充数据库,最快的方法是使用COPY。 我必须填充一个数据库。现在我的写入速度低至每秒100-200。这涉及通过C++库LIPBQXX发送许多单独的插入。我想有两个原因:

数据有许多重复记录,我有原始日志,我解析并发送这些日志。这会导致主键异常。 逐个发送Insert语句。 第一个是我无法控制的。但是我读到了第二本。 据我所知,tablewriter类适合这个目的。然而,它显然遭到了反对。我已经了解到可以使用stdin作为参数进行复制。 但在这些线索之后,我迷失了方向。有人能给我一个解决办法吗

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

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;
    }

}
我早些时候建立了连接,并传递了对它的引用

附:这个问题可能缺少一些细节。如果是这样,请发表评论,我将编辑并添加它们。

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

如文件中所述:

如果允许单独提交每个插入,则PostgreSQL是 为添加的每一行做大量工作

此外:

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

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

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

通常使用两种方法:

避免错误:插入到。。。如果不存在,请从主键=

通过在plpgsql函数中插入忽略itr的异常块来捕获错误。导致重复的特定插入将被取消,但事务不会中止


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

检查您是否没有为每个插入启动新事务。您应该在一个事务中完成所有这些操作。如果可能,请显示相关代码。@DanielVérité我已经添加了我的代码。我怀疑它是否发生在一个事务中,但我不知道如何使用libpqxx控制事务。是的,这段代码提交了每个插入,这是不好的。您想重新构造它,使其只执行w.exec。。对于循环中的每一行,将pqxx::work实例化和w.commit放在此循环之外。那么,您的意思是,像10个w.exec然后一个commit?每个连接或跨所有连接并发插入?换句话说,如果事务是在一个连接上构建的,并且在提交之前有多个exec,那么它们会干扰另一个线程使用另一个连接在另一个表上做同样的事情吗?提前非常感谢@Gracchus:在同一个连接中,不可能同时插入。跨连接,是的,一旦它们竞争锁,它们就会进行干扰。例如,如果目标表有一个主键,则第二次插入事务将等待第一次提交。非常感谢您清除了Daniel Vérité!这是否意味着第二笔交易将失败或无限期延迟?提前非常非常感谢您!