【问题标题】:SQLite queries running slowly, need optimization helpSQLite 查询运行缓慢,需要优化帮助
【发布时间】: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


【解决方案1】:

您缺少索引。见:

DOs and DONTs for Indexes

此外,如果您在 where 子句中输入用户 ID,SELECT MAX(id) FROM tbl_completion GROUP BY tbl_completion.userid, tbl_completion.form_id 可能会丢弃不需要的行。

【讨论】:

  • 我建议两者。 :-) 请参阅有关索引 dos/donts 的帖子,这会更有意义。
【解决方案2】:

听起来您可能遇到了 SQLite 的并发限制。 SQLite 不支持并发写入,所以如果你有很多用户,你最终会有很多争用。您应该考虑迁移到另一个 DBMS 以满足您的扩展需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 2012-10-14
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多