2011-05-26 57 views
2

我有一個SQLite DB,其中一個表中有大約24k條記錄,另一個表中有15條記錄。包含15條記錄的表格包含有關需要由用戶完成的表單(大約1k個用戶)的信息。具有24k記錄的表格保存關於哪些表單由誰以及何時完成的信息。當用戶登錄時,查詢運行時會有大約3/4秒的等待時間,以確定用戶到目前爲止已完成了什麼。我的客戶太長了。我知道我不能以最好的方式進行我的查詢,因爲它們包含在一個循環中。但我似乎無法弄清楚如何優化我的查詢。SQLite查詢運行緩慢,需要優化幫助

運行作爲查詢如下:

1)選擇所有的表格和信息

$result = $db->query("SELECT * FROM tbl_forms"); 
while($row = $result->fetchArray()){ 
//Run other query 2 here 
} 

2)對於每個窗體/行,運行斷定哪些是最近完成查詢有關該表格的信息。

$complete = $db->querySingle("SELECT * FROM tbl_completion AS forms1 
     WHERE userid='{$_SESSION['userid']}' AND form_id='{$row['id']}' AND forms1.id IN 
     (SELECT MAX(id) FROM tbl_completion 
     GROUP BY tbl_completion.userid, tbl_completion.form_id)", true);   

有15種形式,所以總共有16個查詢在運行。但是,對於我的表結構,我不確定如何使用1個連接的查詢來獲取「最近的」(又名最大表單ID)表單信息。

我的表結構看起來像這樣:

tbl_forms: 
id | form_name | deadline | required | type | quicklink 

tbl_completion: 
id | userid | form_id | form_completion | form_path | timestamp | accept | reject 

編輯:

SELECT * FROM tbl_completion AS forms1 
LEFT OUTER JOIN tbl_forms ON forms1.form_id = tbl_forms.id 
WHERE forms1.userid='testuser' AND forms1.id IN 
(SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id) 

這將是最給我起來:Index on tbl_forms (id), Index on tbl_forms (id, form_name), Index on tbl_complete (id)

我使用的查詢就是喜歡嘗試關於已完成表單的最新信息以及表單信息,但唯一的問題是我需要輸出表中的所有表單(如:Form 1 -Incomplete,Form 2-C ompleted等)我似乎無法弄清楚如何讓它與左表工作tbl_forms並獲取所有表單信息,以及「最新」的形式tbl_completion信息。我也試着用最後一張「桌子」做一個3 LOJ,作爲一張臨時表,它保存着maxid,但是速度很慢,並沒有給我想要的東西。

任何人都可以幫忙嗎?有沒有更好的優化查詢我可以運行一次,或者我可以在數據庫方面做一些其他的事情來加速這一點?先謝謝你。

+3

我在這裏看不到任何有關表格索引的信息......這對開始故障排除是必要的。 – 2011-05-26 13:50:04

+0

@Don Dickinson:這將是展示這一點的最佳方式,創作陳述? – Charx 2011-05-26 14:00:47

+0

「xxx'上的索引,'xxx,xxx2'上的索引如何? :)試着在第二個查詢上運行一個EXPLAIN以及(因爲那個可能是壞的)。 – Fge 2011-05-26 14:07:11

回答

2

你錯過了索引。請參閱:

DOs and DONTs for Indexes

此外,SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id大概可以丟棄不需要的行,如果你在你的用戶ID在where子句中折騰。

+0

我會建議兩個。 :-)查看索引dos/donts上的帖子,它會更有意義。 – 2011-05-26 14:41:56

1

這聽起來像你可能會遇到SQLite的併發限制。 SQLite不支持併發寫入,所以如果你有很多用戶,你最終會產生很多爭用。您應該考慮遷移到另一個DBMS以滿足您的擴展需求。