Увеличьте скорость обновления до PostgreSQL базы данных через libpqxx - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь использовать библиотеку libpqxx для чтения и записи в базу данных postgreSQL через C ++. Пример базы данных, который у меня есть, состоит из 3 столбцов и около 16000 строк.

В моем коде я использую work.exe c для передачи sql запроса, и потребовалось 30 + se c для обновления всех 16000 ячеек в 1 столбце. Я не уверен, правильно ли я это делал, или время записи зависит от скорости моего жесткого диска?

Прикрепленный образец кода, который я использовал.

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

Ответы [ 2 ]

2 голосов
/ 20 января 2020

Вы должны выполнить операторы UPDATE в одной транзакции. PostgreSQL работает в режиме автоматической фиксации, поэтому каждый из ваших UPDATE работает в своей собственной транзакции. 16000 сбросов в журнал транзакций - вот что вас убивает.

Начните явную транзакцию с START TRANSACTION и завершите ее с COMMIT.

Это хорошая идея, помимо соображений производительности потому что таким образом модификации данных будут атомы c, то есть все UPDATE будут отменены, если какой-либо из них потерпит неудачу.

0 голосов
/ 21 января 2020

Производительность вашего кода может быть улучшена с помощью подготовленного оператора.

Из документации libpqxx

Если у вас есть оператор SQL, который вы собираетесь выполнить много раз подряд, может быть более эффективно подготовить его один раз и использовать его Это сохраняет базу данных базы данных при разборе комплекса SQL и определении эффективного плана выполнения. Еще один приятный побочный эффект заключается в том, что вам не нужно беспокоиться о экранировании параметров.

Ваш оператор SQL будет выглядеть так:

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

You можно подготовить это один раз, а затем вставить различные значения для $ 1 в вашу l oop.

В документации libpqxx есть пример, к которому вы можете обратиться.

...