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