使用Qt/MySQL批处理模式时的性能

Sil*_*cer 7 mysql sql qt database-performance

我正在使用Qt 5.3.1(Win 7,VS2013)的SQL模块将数据插入到MySQL 5.6数据库中.在我注意到一些性能问题后,我执行了三个测试代码片段并测量了它们的运行时间,以便更好地理解SQL性能.结果令人困惑.

为了测试,我使用了一个"测试"表,其中包含VARCHAR列"test"和每行唯一递增的id.

第一个片段看起来基本上是这样的:

const QString uploadQueryString("INSERT INTO test (test) VALUES ('%1')");
for (int i=0; i<1000; i++)
{
   QSqlQuery uploadQuery(uploadQueryString.arg("A: test text"), dataBase);
   if (uploadQuery.lastError().isValid())
   {
      qDebug() << tr("Query execution failed (%1)").arg(uploadQuery.lastError().text());
   }
}
Run Code Online (Sandbox Code Playgroud)

第二个是这样的:

const QString uploadQueryString("INSERT INTO test (test) VALUES %1");

QStringList values;
for (int j=0; j<1000; j++)
{
   values.append("\"B: test text\"");
}

QString valuesString = "("+ContainerToString(values, "), (")+")";

QSqlQuery uploadQuery(uploadQueryString.arg(valuesString), dataBase);
if (uploadQuery.lastError().isValid())
{
   qDebug() << tr("Query execution failed (%1)").arg(uploadQuery.lastError().text());
}
Run Code Online (Sandbox Code Playgroud)

第三个是这样的:

const QString uploadQueryString("INSERT INTO test (test) VALUES (:values)");

QVariantList values;
for (int j=0; j<1000; j++)
{
   values.append("C: test text");
}

QSqlQuery batchQuery(dataBase);
if (batchQuery.prepare(uploadQueryString))
{
   batchQuery.bindValue(":values", values);

   if (!batchQuery.execBatch())
   {
      qDebug() << tr("Batch query execution failed (%1)").arg(batchQuery.lastError().text());
   }
}
else
{
   qDebug() << tr("Unable to prepare batch query");
}
Run Code Online (Sandbox Code Playgroud)

我执行了10次这些片段(包括打开/关闭代码):

1. 10x1000 basic inserts
Ticks delta: 318617 ms; Kernel delta: 358 ms; User delta: 1201 ms; Process delta 1559 ms

2. 10x1000 by value list insert
Ticks delta: 3011 ms; Kernel delta: 0 ms; User delta: 46 ms; Process delta 46 ms

3. 10x1000 by batch insert
Ticks delta: 631679 ms; Kernel delta: 811 ms; User delta: 998 ms; Process delta 1809 ms
Run Code Online (Sandbox Code Playgroud)

"Ticks delta"是每个片段所需的时间."内核增量"和"用户增量"是实际活动的用户和内核处理时间,而"进程增量"是内核和用户时间的总和.

第一个结果是预期的:执行10x1000单个查询需要大量时间(特别是由于延迟).

第二个结果也像预期的那样:执行包含所有行的单个查询非常快.

唉第三个结果让我很困惑:我期望批处理模式更快!即使在最坏的情况下(如果驱动程序使用Qt文档所说的单个查询模拟批处理执行),它应该与第一个代码段一样慢.实际上它需要两倍的时间!

批处理执行在Qt/MySQL中实际做了什么?有没有办法提高批量执行性能?execBatch()执行单个查询的可能性有多大?

小智 2

QMYSQL不支持BatchExec。

您可以使用 QSqlDriver::hasFeature(QSqlDriver::BatchOperations) 来检查驱动程序是否支持 Batchexec。

您还可以在 QT_SRC/src/sql/drivers/mysql/qsql_mysql.cpp 中检查源代码

bool QMYSQLDriver::hasFeature(DriverFeature f) const

它只是返回 false。