如何使sqlite内存数据库连接查询与MySQL一样快

时间:2015-07-15 19:39:01

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

我有一个非常复杂的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内存数据库中运行它(在Linux上使用Perl)时,大约需要20分钟。这仍然是可以接受的。

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

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

在MySQL中需要40秒。在sqlite内存数据库中(在Linux上使用Perl),我等了一个多小时,但它仍然没有完成。

我需要进行哪种调整才能使查询更快?我的门槛在1小时之内。

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

先谢谢你的帮助!!

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:-2)

为了加快查询速度,您需要对以下某项进行一些更改:

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

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

找到