【发布时间】:2011-09-02 15:03:52
【问题描述】:
我有一个 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 信息。我还尝试使用最后一个“表”作为保存 maxid 的临时表进行 3 LOJ,但它非常慢并且没有给我想要的东西。
有人可以帮忙吗?是否有更好的优化查询我可以运行一次,或者我可以在数据库端做其他事情来加快速度?提前谢谢你。
【问题讨论】:
-
我在这里看不到任何有关如何为您的表编制索引的信息......这是开始故障排除所必需的。
-
@Don Dickinson:哪一种是展示这一点的最佳方式,创作声明?
-
“'xxx' 上的索引,'xxx,xxx2' 上的索引”怎么样? :) 尝试在第二个查询上运行 EXPLAIN (因为那个可能是坏的)。
-
您认为您的系统可以将数据库拆分为更小的数据库吗?
-
@Fge:添加了有关索引的信息——这些信息可能根本没有它们应有的有用。我也在尝试做一个解释查询计划。感谢您的建议,顺便说一句
标签: php sql sqlite optimization