我正在开发一个涉及大量 sql 查询的 Qt(C++) 项目。基本上它是一个update()
被调用约 1000次的函数。在我的系统中,每次调用大约需要 25 - 30 毫秒,导致总执行时间长达 30 秒。我相信这个程序可以优化,从而减少时间消耗,但不知道如何优化。这是功能-
void mediaProp::update(){
static QSqlQuery q1, q2, q3;
static bool firstCall = true;
static QString stable;
QString table = this->type+"s";
if(firstCall){
stable = table;
q1.prepare("SELECT id FROM titles WHERE lower(title)= lower(:a) AND type = :b COLLATE NOCASE");
q2.prepare("INSERT INTO " + table + "(pic_id, score) VALUES (0, 0)");
q3.prepare("INSERT INTO titles (id, type, title) VALUES (:a, :b, :c)");
firstCall = false;
}
else if(stable != table){
stable = table;
q2.prepare("INSERT INTO " + table + "(pic_id, score) VALUES (0, 0)");
}
q1.bindValue(":a", this->title);
q1.bindValue(":b", dbEnums(this->type));
q1.exec();
q1.last();
int size = q1.at() + 1;
if( size > 0){
q1.first();
this->id = q1.value("id").toInt();
}
else if( !this->title.trimmed().isEmpty() ){
q2.exec();
this->id = q2.lastInsertId().toUInt();
q3.bindValue(":a", this->id);
q3.bindValue(":b", dbEnums(this->type));
q3.bindValue(":c", this->title);
q3.exec();
}
else{
this->id = 0;
}
}
任何建议或帮助都会非常棒!谢谢 :)
编辑- 正如Yohan Danvin所建议的,我对函数进行了更改并在上面进行了更新。
EDIT2 - Yohan Danvin 的概念很聪明,我也相信使用准备好的语句作为静态变量可以优化例程。但它并没有像我们预期的那样工作。整个例程并没有花费更少的时间,而是花费了更多的时间。奇怪的是,准备好的陈述使事情变得更糟!但是后来经过大量挖掘,我发现了为什么会这样-
THE PROCEDURE TOOK 25 MILLISECONDS IN AVERAGE
AFTER USING Yohan's STATIC PREPARED STATEMENT MAPPING PROCEDURE- IT TOOK 27ms IN AVG
作为记录,我使用文件作为我的数据库而不是内存。每次执行 INSERT 查询时,QSqlQuery 都会创建一个临时转储文件并将其附加到主数据库文件中。与内存相比,访问文件非常耗时,并且导致 25 毫秒/插入速度很慢。我想当我使用 Yohan 的概念时,由于功能开销等原因,它花费了更多时间。如果我错了,请告诉我!最后我遇到了http://www.sqlite.org/pragma.html并更改了一些 pragma 参数-
QSqlQuery("PRAGMA journal_mode = OFF");
QSqlQuery("PRAGMA synchronous = OFF");
这就像魅力!执行速度从每个例程调用 25 毫秒下降到每 3 个例程调用 1 毫秒。这是一个巨大的差距!基本上设置pragma journal_mode = OFF
告诉 SQLITE 不要创建单独的临时转储文件,并PRAGMA synchronous = OFF
在执行所有查询后将更改应用于数据库。可能是,通过使用临时内存数据库。如果我提出了错误的观点,请告诉我。
我很高兴这个程序现在快了145倍!