首页 > 解决方案 > Qt SQL Lite:查询真的很慢

问题描述

第一次使用 Qt SQLite 用户。我想用一些随机数据创建一个数据库,以便开始测试查询。我要填充一些数据的第一个表是一个典型的客户表,其中包含姓名、姓氏、个人 ID、电话和出生日期。我有随机生成的名字和生日的文本文件,然后我随机生成其他的东西。这是代码:

#include <QCoreApplication>
#include <QtSql>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QElapsedTimer>

#define  DBFILE  "fhdb"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile(DBFILE).remove();

    if (!QFile(DBFILE).exists()){
        // DB must be created.
        QFile file(":/fhmakedb.sql");
        if (!file.open(QFile::ReadOnly)){
            qWarning() << "Cannot open DB Creation script";
            return 0;
        }
        QTextStream reader(&file);
        QString script = reader.readAll();
        file.close();

        QStringList commands = script.split(";",QString::SkipEmptyParts);

        // Reading each command
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName(DBFILE);

        if (!db.open())
            qWarning() << "DBERROR" << db.lastError().text();

        QSqlQuery q;
        for (int i = 0; i < commands.size(); i++){
            if (!q.exec(commands.at(i))){
                qWarning() << "QEXECERROR" << q.lastError().text();
            }
        }
        qWarning() << "All done";

    }
    else{
        qWarning() << "DB Already exists";
    }

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(DBFILE);

    if (!db.open())
        qWarning() << "DBERROR" << db.lastError().text();

    QFile file(":/lnames");
    file.open(QFile::ReadOnly);
    QTextStream reader(&file);
    QString data = reader.readAll();
    file.close();

    QStringList lines = data.split("\n");
    lines.removeLast();
    QElapsedTimer timer;
    for (int i = 0; i < lines.size(); i++){

        // Generating DNI
        qint32 base = qrand() % 999999;
        qint32 top  = qrand() % 5;
        qint32 DNI = base + (30+top)*1000000;

        // Generating number
        base = qrand() % 999999;
        qint32 tel = base + 15000000;

        QStringList row = lines.at(i).split(" ",QString::SkipEmptyParts);
        qWarning() << "ROW" << row;
        QString query = "INSERT INTO tALumnos (Nombre, Apellido, DNI, Nacimiento, Telefono) VALUES(";
        query = query + "'" + row.at(0) + "',";
        query = query + "'" + row.at(1) + "',";
        query = query + "'" + QString::number(DNI) + "',";
        query = query + "'" + row.at(2) + "',";
        query = query + "'" + QString::number(tel) + "')";
        timer.start();
        QSqlQuery q;
        if (!q.exec(query)){
            qWarning() << query << "FAILED" << q.lastError().text();
            return 0;
        }
        qWarning() << "QUERY TOOK: "  << timer.elapsed();

    }
    qWarning() << "FINISHED";


    // Data.


    return a.exec();
}

行中的每一行包含用空格分隔的姓名、姓氏和出生日期。

我的问题是这非常慢。授予它一次性的东西,但我担心它是我必须执行更复杂查询时的性能指标。查询给出的平均时间约为 125 毫秒,这似乎太大了。

我在这里做错了吗?

谢谢你的帮助。

标签: sqlqt

解决方案


每个查询都在 exec() 调用期间写入磁盘,因此硬件 I/O 是您的瓶颈。使用事务来防止这种情况。IE

if (!db.open()) [...]
if (!db.transaction()) [...]
for [...]
    [...]q.exec(qry);[...]
if (!db.commit()) [...]

SQLite 文档有更多关于事务的信息。


推荐阅读