Qt SQL Lite:查询真的很慢

时间:2018-07-03 10:57:46

标签: sql qt

第一个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毫秒,这似乎太大了。

我在这里做错什么了吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

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

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

SQLite文档提供了有关交易的更多信息。