开发者

SQLite queries running slowly, need optimization help

I have a SQLite DB with about 24k records in one of the tables, 15 in the other. The table with 15 records holds information about forms that need to be completed by users (roughly 1k users). The table with 24k records holds information about which forms have been completed by who, and when. When a user logs in, there is about a ~3/4 second wait time while the queries run to determine what the user has finished so far. Too long for my client. I know I can't be doing my queries in the best way, because they are contained within a loop. But I cannot seem to figure out how to optimize my query.

The queries run as follows:

1) Select all of the forms and information

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

2) For each form/row, run a query that figures out what is the most recent completion information about that form for the user.

$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);          

There are 15 forms, so there is a total of 16 queries running. However, with my table structure, I'm unsure as how to get the "most recent" (aka max form id) form information using 1 joined query instead.

My table structure looks like so:

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

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

Edit: Index on tbl_forms (id), Index on tbl_forms (id, form_name), Index on tbl_complete (id)

I've tried using a query that is like:

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)

Which will give me the most up-to-date information about the forms completed, as well as the form information, but the only problem with this is I need to output all the forms in a table (like: Form 1-Incomplete, Form 2-Completed, etc) I cannot seem to figure out how to get it to work with the left table being tbl_forms and getting all form info, as well as "l开发者_StackOverflow中文版atest" form tbl_completion info. I also tried doing a 3 LOJ with the last "table" as a temp table holding the maxid, but it was very slow AND didn't give me what I wanted.

Can anybody help?? Is there a better optimized query I can run once, or can I do something else on the DB side to speed this up? Thank you in advance.


You're missing indexes. See:

DOs and DONTs for Indexes

Also, the SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id could presumably discard unneeded rows if you toss in your userid in a where clause.


It sounds like you might be running into the concurrency limitations of SQLite. SQLite does not support concurrent writes, so if you have a lot of users, you end up having a lot of contention. You should consider migrating to another DBMS in order to satisfy your scaling needs.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜