要在PostgreSQL中插入大容量数据/填充数据库,最快的方法是使用复制。来源
我必须填充一个数据库。现在,我得到的写速度低到100-200每秒.这涉及到通过C++库libpqxx发送许多单独的插入。我认为有两个原因:
第一个是我无法控制的。然而,我读到了关于第二篇文章的文章。
据我所知,制表类适合这一目的。然而,它显然遭到了反对。我读过,可以使用stdin作为复制的参数。
但在这些线索之后我迷失了方向。有人能帮我找到解决方案吗?
编辑:下面是代码,其中有一个执行状态的函数:
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:这个问题可能缺乏一些细节。如果是,请评论,我将编辑和添加他们。
发布于 2013-10-30 18:19:44
pushLog函数分别提交每个插入,而且提交速度很慢。
正如文档的填充数据库所解释的那样
如果允许单独提交每个插入,则PostgreSQL将对所添加的每一行进行大量工作。
另外:
在一个事务中执行所有插入的另一个好处是,如果插入一行失败,那么插入到该点的所有行的插入都会回滚,因此您不会被部分加载的数据困住。
但是,在您的情况下,这将是一个问题,而不是一个好处,因为每次插入都可能在主键冲突时失败,从而取消了上次提交后的先前插入。请注意,如果您使用COPY,这也是一个问题。
由于确实有必要对事务中的查询进行分组以提高性能,因此您需要以一种不中止事务的方式处理主键冲突。
通常使用两种方法:
INSERT INTO... WHERE NOT EXISTS (SELECT 1 FROM table WHERE primary_key=...)如果您有并发插入,则需要使用锁定策略对这些方法进行细化。
https://stackoverflow.com/questions/19684168
复制相似问题