我有一个SQLite数据库,其中一个表中有大约24k个记录,另一个表中有15个记录。包含15条记录的表包含有关用户需要填写的表单的信息(大约1k用户)。具有24k记录的表格保存有关哪些表格已由谁以及何时完成的信息。当用户登录时,在查询运行时大约有大约3/4秒的等待时间来确定用户到目前为止已完成的内容。我的客户太久了。我知道我不能以最好的方式进行查询,因为它们包含在循环中。但我似乎无法弄清楚如何优化我的查询。
查询运行如下:
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
修改:Index on tbl_forms (id), Index on tbl_forms (id, form_name), Index on tbl_complete (id)
我尝试使用类似的查询:
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)
这将为我提供有关已完成表单的最新信息以及表单信息,但唯一的问题是我需要在表格中输出所有表格(如:表格1-不完整,表单2完成等)我似乎无法弄清楚如何使用左表作为tbl_forms并获取所有表单信息,以及“最新”表单tbl_completion信息。我也尝试用最后一个“表”做一个3 LOJ作为一个持有maxid的临时表,但它非常慢并且没有给我我想要的东西。
任何人都可以帮忙吗?是否有一个更好的优化查询,我可以运行一次,或者我可以在数据库端执行其他操作来加快速度吗?提前谢谢。
答案 0 :(得分:2)
您缺少索引。参见:
此外,如果你在where子句中输入你的用户ID,SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id
可能会丢弃不需要的行。
答案 1 :(得分:1)
听起来您可能遇到了SQLite的并发限制。 SQLite不支持并发写入,所以如果你有很多用户,你最终会有很多争用。您应该考虑迁移到另一个DBMS以满足您的扩展需求。