通过libpqxx提高对PostgreSQL数据库的更新速度

问题描述 投票:0回答:2

我正在尝试使用libpqxx库通过C ++读写postgreSQL数据库。我拥有的示例数据库是3列,大约16000行。

在我的代码中,我使用work.exec来传递sql查询,并且花了30 + sec来更新1列中的所有16000个单元格。我不确定是否执行不正确,或者写入时间取决于我的硬盘速度?

附上我使用的示例代码。

#include <string>
#include <vector>
#include <chrono> 
#include <iostream>
#include <fstream>
#include <sstream>

#include <pqxx/pqxx>

using namespace std;
using namespace std::chrono;

auto start = high_resolution_clock::now();

int main(int argc, char* argv[])
{
       //open connection to postgresql database
    pqxx::connection con("host=localhost port=5432 dbname=postgres user=postgres password=P@$$w0rd");
       //"pqxx::work" is an transaction type object in libpqxx, use to transfer SQL query or command
    pqxx::work wrk(con);
       //"pqxx:result" set containing data returned by a query or command
    pqxx::result res = wrk.exec("SELECT * FROM signal");

    for (int i = 0; i < res.size(); i++)
    {
       wrk.exec("UPDATE public.signal SET signalvalue = signalvalue + 1 WHERE indexid ="+to_string(i)+";");
    }

    wrk.commit();

    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cout << "Time taken by function: " << duration.count() << " microseconds" << endl;
    cin.get();
    return 0;
}
c++ postgresql performance database-connection libpqxx
2个回答
2
投票

您必须在单个事务中运行UPDATE语句。 PostgreSQL在自动提交模式下工作,因此每个UPDATE都在自己的事务中运行。 16000刷新到事务日志是杀死您的原因。

START TRANSACTION开始显式事务,以COMMIT结束。

除了性能方面的考虑外,这是一个好主意,因为通过这种方式,数据修改是原子的,也就是说,如果其中任何一个失败,所有的UPDATE都将被撤消。


0
投票

可以通过使用准备好的语句来提高代码的性能。

来自libpqxx文档

如果您有一条要快速连续执行多次的SQL语句,则准备一次并重用它可能会更有效。这样可以节省数据库后端解析复杂SQL和确定有效执行计划的工作量。另一个不错的副作用是,您不必担心转义参数。

您的SQL语句看起来像

UPDATE public.signal SET signalvalue = signalvalue + 1 WHERE indexid = $1

您可以准备一次,然后在循环中为$ 1插入不同的值。

The libpqxx documentation有一个示例可以参考。

© www.soinside.com 2019 - 2024. All rights reserved.