sql - 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 毫秒,这似乎太大了。
我在这里做错了吗?
谢谢你的帮助。
解决方案
每个查询都在 exec() 调用期间写入磁盘,因此硬件 I/O 是您的瓶颈。使用事务来防止这种情况。IE
if (!db.open()) [...]
if (!db.transaction()) [...]
for [...]
[...]q.exec(qry);[...]
if (!db.commit()) [...]
SQLite 文档有更多关于事务的信息。
推荐阅读
- tidb - 使用 Spark 写入 TiDB 时出现错误 GC life time is short than transaction duration
- python - 没有名为 cairo 的模块 - python 和 pip
- jenkins - 无法使用来自 Jenkins Groovy 的 aws cli
- python - TypeError:使用 .apply 更新数据框列时,字符串索引必须是整数
- elasticsearch - 如何在elasticsearch的嵌套类型字段中找到不同的值?谁能提供一个例子?
- database - 有人知道水平和垂直传播吗
- redis - redis集群模式下,我们加载脚本时返回的SHA值是一样的吗?
- amazon-web-services - Keras,GPU内存不足
- python - 是否可以使用 FFmpeg 从视频文件夹中剪切“随机”部分并将它们连接成 1 个视频?
- mysql - MySQL查询计算行之间的时间差异