gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:25:39 27 4
gpt4 key购买 nike

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

  1. 数据有很多重复记录。(我有原始日志,我解析并发送。)导致主键异常。
  2. 插入语句的逐一发送。

第一个不在我手中。但是我正在阅读第二个。
据我所知,tablewriter 类适合这个目的。但是,它显然已被弃用。我读过可以使用标准输入作为参数进行复制。
但是在这些线索之后我迷路了。有人可以引导我找到解决方案吗?

编辑:这是代码,其中我有一个执行语句的函数:

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:问题可能缺少一些细节。如果是这样,请发表评论,我会编辑并添加它们。

最佳答案

pushLog 函数单独提交每个插入,而且提交很慢。

如文档的 Populating a Database 中所述:

If you allow each insertion to be committed separately, PostgreSQL is doing a lot of work for each row that is added

还有:

An additional benefit of doing all insertions in one transaction is that if the insertion of one row were to fail then the insertion of all rows inserted up to that point would be rolled back, so you won't be stuck with partially loaded data

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

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

通常使用两种方法:

  1. 避免错误:INSERT INTO...WHERE NOT EXISTS (SELECT 1 FROM table WHERE primary_key=...)

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

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

关于c++ - 使用 libpqxx 批量存储数据或如何在 libpqxx 中使用 COPY 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19684168/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com