【问题标题】:How to make sqlite in-memory db join query as fast as MySQL如何使 sqlite 内存数据库连接查询与 MySQL 一样快
【发布时间】:2015-10-05 00:50:45
【问题描述】:

我有一个非常复杂的 sql 查询 - 逻辑很简单,但我需要连接 17 个表(每个表有 10-20 个字段和 100 到 100 万条记录),所以有很多(LEFT)JOIN 和 WHERE条款。

SELECT table1.column_A
       table2.column_B
       table3.column_C
       table4.column_D
       ....
FROM table1
LEFT JOIN table2 ON table1.column_a = table2.column_b
JOIN table3 ON table3.column_c = table1.column_d
LEFT JOIN table4.column_e = table3.column_f
    AND LENGTH(table4.column_g) > 6 AND (table4.column_h IN (123,234))
LEFT JOIN ....
....
WHERE table1.column_i = 21 
    AND (table1.column_j IS NULL OR DATE(table1.column_k) <> DATE(table1.column_l))

上面的查询只需要 5 秒就可以在 MySQL 中运行。但是当我在 sqlite in-memory db 中运行它(在 Linux 上使用 Perl)时,大约需要 20 分钟。这还是可以接受的。

当我添加一个 ORDER BY 子句(我确实需要这个)时,执行时间会急剧增加。

ORDER BY table1.column_m, table6.column_n, table7.column_o IS NULL;

在 MySQL 中需要 40 秒。在 sqlite in-memory db 中(在 Linux 上使用 Perl),我等了一个多小时,但仍然没有完成。

我需要做什么样的调整来加快查询速度?我的阈值在 1 小时内。

我将其设为内存数据库的原因是我收到了 SQL 生成的规范化数据,但我们最终需要将数据加载到非 SQL 数据库中,所以我不想创建中间 SQL db 仅用于数据加载 - 这使代码变得丑陋并增加了维护复杂性。另外,我目前面临的时间问题只是一次性的。未来我们每天收到的数据量会小很多(不到我今天的1%)

提前感谢您的帮助!!

【问题讨论】:

  • 如果不查看表结构和正在运行的确切查询,可能很难解决性能问题。由于您正在使用大量表,因此我建议您只使用几个测试表创建一个类似查询的minimal, complete, verifiable example。然后您可以显示您在 MySQL 和 SQLite 中使用的表定义,以及每个表的时间。
  • MySQL 表是在内存中(ENGINE = MEMORY)还是标准表?不要忘记在 Perl 中对结果进行排序可能会更快
  • MySQL 表是标准表(在 Windows 上),而 sqlite 在 Linux 上是内存表。
  • 数据库可能在内存中,但这并不意味着磁盘没有发挥作用,尤其是当您加入大量大型表时。购买足够大的 SSD 并升级内存。

标签: mysql database perl sqlite in-memory-database


【解决方案1】:

您的 ORDER BY 子句位于 3 个不同表的列上。再多的查询优化或索引创建都不会改变 DBMS 必须在生成结果集之后(或之后)进行外部排序的事实。如果您限制了 SQLite 可以使用的内存量(我不是 SQLite 专家,但我认为这至少是可能的,如果不需要的话),那么这可能是原因(例如,它正在经历一些令人难以置信的阴谋在其范围内完成工作)。或者它只是挂了。您等待的那个小时的 CPU 利用率是多少? I/O 呢(它是否因为 SQLite 可以使用的内存量没有限制而颠簸,正如 Sinan 所暗示的那样)?

【讨论】:

    【解决方案2】:

    为了使您的查询更快,您需要对以下其中一项进行一些更改:

    • 查询的编写方法
    • 数据库表结构
    • 制作适当的索引

    所有这些你都可以在http://www.perlmonks.org/?node_id=273952找到

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      • 2015-01-06
      相关资源
      最近更新 更多