qt - PostgreSQL 中的快速批处理

标签 qt postgresql

我有很多数据,我想在最短的时间内插入到数据库中。我做了一些测试。我在 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/

相关文章:

sql - 如何计算一个表中的值,然后在另一个表中显示相同的值?

json - 在 Postgresql 中将文本类型列转换为 json 类型

sql - 从与分数成比例的组中抽取样本

Qt3d QML : how to add Text as overlay to a standard example

php - PostgreSQL PDO 插入数组类型

python - 内部加入 Django 1.9

qt - 如何确定是否在 QItemDelegate 的paint() 函数中选择了该项目?

c++ - 防止 Qt 窗口在 Hook 的应用程序中关闭,Eventfilter 不执行任何操作

c++ - Qt/C++ 中的简单文本编辑器

c - 如何推送(使用 libgit2)