MySQL事务和缓冲的请求列表

时间:2018-06-06 12:11:05

标签: c++ mysql libmysql

我有一个C ++代码,它根据这些文件的内容解析文件并更新MySQL数据库。 我使用MySQL 5.7在Windows 10中运行我的代码,我的基础使用InnoDB引擎。 MySQL调用是通过我自己的libmysql包装器执行的。

在尝试优化此代码时,我将更新请求附加到缓冲区中,直到达到缓冲区的最大大小,然后同时发送整个缓冲区(包含N个更新)。整个过程在一次交易中完成。

以下是我的代码的外观:

MySQLWrapper.StartTransaction();

string QueryBuffer = "";

// Element count is the number of elements parsed from the files
for( int i = 0 ; i < ElementCount ; ++i )
{
bool FlushBuffer = 
( i> 0 && ! (( i + 1 ) % N) )    ||
( i == ElementCount - 1 ); // determines if we have reached the buffer max number of requests

QueryBuffer += "INSERT INTO mytable (myfield) VALUES (" Element[ i ] ");";

if( FlushBuffer )
{
MySQLWrapper.SendRequest( QueryBuffer );
QueryBuffer.assign("");
}
}
MySQLWrapper.Commit();

SendRequest(字符串请求)的实现基本上是:

void SendRequest(string Request)
{
mysql_query( SQLSocket, Request.c_str())
}

但是,在提交事务时,事务恰好已被破坏:MySQL表示状态不正确。我试图做同样的事情,但发送请求ony,并且这个错误不会发生在提交时。

所以,我的两个问题是:

  1. 您知道为什么一次发送多个请求的事实会破坏我的交易吗?
  2. 您是否认为使用缓冲的请求列表可以真正优化我的代码?

1 个答案:

答案 0 :(得分:0)

创建一个具有多个值的INSERT,而不是多个INSERT。 IOW,在循环之前, 拥有INSERT INTO TABLE (columns),然后在循环内,为每个值集附加(values),

MySQLWrapper.StartTransaction();

string QueryBuffer = "INSERT INTO mytable (myfield) VALUES ";

// Element count is the number of elements parsed from the files
for( int i = 0 ; i < ElementCount ; ++i )
{
    bool FlushBuffer = 
    ( i> 0 && ! (( i + 1 ) % N) )    ||
    ( i == ElementCount - 1 ); // determines if we have reached the buffer max number of requests

    QueryBuffer += "(" Element[ i ] ")";
    if( flushbuffer ) {
        QueryBuffer += ";";
    } else {
        QueryBuffer += ",";
    }

    if( FlushBuffer )
    {
        MySQLWrapper.SendRequest( QueryBuffer );
        QueryBuffer.assign("");
    }
}
MySQLWrapper.Commit();

生成的SQL语句将类似于:

INSERT INTO mytable
(myfield)
VALUES
(1),
(2),
(3),
(3);