title: SQLite queries running slowly, need optimization help
body: <p>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.</p>
  
  <p>The queries run as follows:</p>
  
  <p>1) Select all of the forms and information</p>
  
  <pre><code>$result = $db-&gt;query("SELECT * FROM tbl_forms");
  while($row = $result-&gt;fetchArray()){
  //Run other query 2 here
  }
  </code></pre>
  
  <p>2) For each form/row, run a query that figures out what is the most recent completion information about that form for the user.</p>
  
  <pre><code>$complete = $db-&gt;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);          
  </code></pre>
  
  <p>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.</p>
  
  <p>My table structure looks like so:</p>
  
  <pre><code>tbl_forms:
  id | form_name | deadline | required | type | quicklink
  
  tbl_completion:
  id | userid | form_id | form_completion | form_path | timestamp | accept | reject
  </code></pre>
  
  <p>Edit: <code>Index on tbl_forms (id), Index on tbl_forms (id, form_name), Index on tbl_complete (id)</code></p>
  
  <p>I've tried using a query that is like:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>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 "latest" 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. </p>
  
  <p>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.</p>