我有很多数据,我想在最短的时间内插入到数据库中。我做了一些测试。我在 PostgreSQL 中创建了一个表(使用以下脚本):
CREATE TABLE test_table
(
id serial NOT NULL,
item integer NOT NULL,
count integer NOT NULL,
CONSTRAINT test_table_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE test_table OWNER TO postgres;
我编写了测试代码,创建了 1000 个随机值并以两种不同的方式插入到 test_table
中。首先,使用 QSqlQuery::exec()
int insert() {
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("TestDB");
db.setUserName("postgres");
db.setPassword("1234");
if (!db.open()) {
qDebug() << "can not open DB";
return -1;
}
QString queryString = QString("INSERT INTO test_table (item, count)"
" VALUES (:item, :count)");
QSqlQuery query;
query.prepare(queryString);
QDateTime start = QDateTime::currentDateTime();
for (int i = 0; i < 1000; i++) {
query.bindValue(":item", qrand());
query.bindValue(":count", qrand());
if (!query.exec()) {
qDebug() << query.lastQuery();
qDebug() << query.lastError();
}
} //end of for i
QDateTime end = QDateTime::currentDateTime();
int diff = start.msecsTo(end);
return diff;
}
第二次使用QSqlQuery::execBatch
:
int batchInsert() {
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("TestDB");
db.setUserName("postgres");
db.setPassword("1234");
if (!db.open()) {
qDebug() << "can not open DB";
return -1;
}
QString queryString = QString("INSERT INTO test_table (item, count)"
" VALUES (:item, :count)");
QSqlQuery query;
query.prepare(queryString);
QVariantList itemList;
QVariantList CountList;
QDateTime start = QDateTime::currentDateTime();
for (int i = 0; i < 1000; i++) {
itemList.append(qrand());
CountList.append(qrand());
} //end of for i
query.addBindValue(itemList);
query.addBindValue(CountList);
if (!query.execBatch())
qDebug() << query.lastError();
QDateTime end = QDateTime::currentDateTime();
int diff = start.msecsTo(end);
return diff;
}
我发现它们之间没有区别:
int main() {
qDebug() << insert() << batchInsert();
return 1;}
结果:
14270 14663 (milliseconds)
我怎样才能改进它?
在http://doc.qt.io/qt-5/qsqlquery.html#execBatch已被引用:
If the database doesn't support batch executions, the driver will simulate it using conventional exec() calls.
我不确定我的 DBMS 是否支持批量执行? 我该如何测试它?
最佳答案
不确定 qt 驱动程序的作用,但 PostgreSQL 可以支持在一个事务中运行多个语句。只需手动执行,而不是尝试使用驱动程序的内置功能。</p>
尝试将您的 SQL 语句更改为
BEGIN TRANSACTION;
对于循环的每次迭代运行插入语句。
INSERT HERE;
一旦所有 1000 条记录发生循环结束,就发出这个。在同一个连接上。
COMMIT TRANSACTION;
另外 1000 行测试用量不大,您可能想尝试 100,000 行或更多行以确保 qt 批处理确实没有帮助。
关于qt - PostgreSQL 中的快速批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7782842/