我正在研究涉及大量sql查询的Qt(C++)项目。基本上它是一个函数update()
,它被称为〜1000次。在我的系统中,每次通话大约需要25 - 30ms,总共可以执行30秒的总执行时间。我相信这个例程可以优化,从而减少时间消耗,但不知道如何优化。这里是功能 -如何优化涉及大量sql查询的Qt代码块?
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;
}
}
任何建议或帮助将是真是太神奇了! 谢谢:)
编辑 - 作为建议的勒芒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都会创建一个临时转储文件并将其附加到主数据库文件中。与内存相比,访问文件非常耗时,导致插入速率慢了25ms。我想当我使用Yohan的概念时,由于功能开销等原因需要更多时间。如果我错了,请告诉我!最后我碰到http://www.sqlite.org/pragma.html和改变了一些编译参数 -
QSqlQuery("PRAGMA journal_mode = OFF");
QSqlQuery("PRAGMA synchronous = OFF");
这工作就像魅力!执行速度从每次例行呼叫25毫秒降至每3次例行呼叫1毫秒。这是一个巨大的差距!基本上设置pragma journal_mode = OFF
告诉SQLITE不要创建一个单独的临时转储文件,并且PRAGMA synchronous = OFF
在执行所有查询后将更改应用于数据库。可能是,通过使用临时内存数据库。如果我提出了一个错误的观点,请让我知道。
我很高兴现在的例程是145X更快!
假设您的数据库有事务,您是在执行1000个事务还是只有一个?这在性能方面完全不同。 –