libpqxx:如何绑定参数数组

时间:2017-02-02 12:59:55

标签: c++ postgresql libpqxx

我希望尽快在postgres表中插入许多参数。

现在我浪费了太多时间来逐个绑定参数。代码看起来几乎像这样:

pqxx::connection my_connection(c_string);
my_connection.prepare("insert_to_db", "INSERT INTO t (id, name) VALUES ($1, $2));

pqxx::work W(my_connection);
for (int i = 0; i < 10000; i++)
{
  W.prepared("insert_to_db")(i)("Max").exec();
}
W.commit();

正如我所看到的,commit 10 000个元素需要0.001秒甚至更少,但绑定大约需要10秒。

我希望将所有参数绑定为值数组。怎么用pqxx呢? 或者有更好的方法来缩短时间?

2 个答案:

答案 0 :(得分:1)

尽可能使用pqxx :: prepare :: invocation,并在执行之前绑定更多值,因为它更稳定且预防错误,但是我在下面描述的方法更快。在您的示例中,每次都执行准备好的语句,因此您不必要地与数据库进行通信。

予。 通过调用:

pqxx::nontransaction W(C);
std::string m_insertCommand = "INSERT INTO tableforperftest(column1, column2) VALUES";


unsigned  int m_nCurrentRow = 32767;

for (size_t i = 0; i < m_nCurrentRow; i++)
{
    unsigned int countOf$ = i * 2;
    for (unsigned int i = 0; i < 2; ++i)
    {
        if (i == 0)
        {
            m_insertCommand += "(";
        }
        else
        {
            m_insertCommand += ", ";
        }
        m_insertCommand += "$";
        std::stringstream ss;
        ss << countOf$ + i + 1;
        m_insertCommand += ss.str();
    }
   if(i < m_nCurrentRow - 1)
    m_insertCommand += ") ,";
}
m_insertCommand += ")";

C.prepare("insert_into_db", m_insertCommand);
pqxx::prepare::invocation inv = W.prepared("insert_into_db");

for (size_t i = 0; i < m_nCurrentRow; i++)
{
    inv(i)(i);
}

inv.exec();

II。 使用存储过程可以获得更多参数值:

CREATE OR REPLACE FUNCTION insertintoboosted(valuesforinsert TEXT) RETURNS VOID AS
$$ 
BEGIN
     EXECUTE 'INSERT INTO tableforperftestproof(column1, column2) VALUES (' || valuesforinsert || ')';
END;
$$
LANGUAGE plpgsql;

代码:

for (size_t i = 0; i < m_nCurrentRow; i++)
{

    if (i == 0)
        ss  << i << "," << i;
    else
        ss << "(" << i << "," << i;

    if (i < m_nCurrentRow - 1)
        ss << "),";
}

C.prepare("prep2", "select insertintoboosted($1::text)");

W.prepared("prep2")(ss).exec();

III。 使用参数绑定和每次执行:

std::string m_insertCommand3 = "INSERT INTO tableforperftest(column1, column2) VALUES ($1, $2)";
C.prepare("insert_into_db3", m_insertCommand3);
for (size_t i = 0; i < m_nCurrentRow; i++)
{
    W.prepared("insert_into_db3")(i)(i).exec();
}

将解决方案与32767插入物进行比较:

Invocation:                              --> Elapsed:    0.250292s
Stored Proc:                             --> Elapsed:    0.154507s 
Parameter binding + execution each time: --> Elapsed:    29.5566s

答案 1 :(得分:0)

pqxx::connection c;
pqxx::work w(c);
c.prepare("prep", "select stored_proc($1::text[])");
auto r = w.prepared("prep")("{v1, v2}").exec();