我正在研究涉及大量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個事務還是隻有一個?這在性能方面完全不同。 –