2011-11-04 42 views
1

我在sqlite中使用SELECT语句时遇到了一些奇怪的行为。有一张桌子有三百万条记录。例如。ORDER BY +和sqlite的性能问题

SELECT * FROM table1 WHERE cond1; 

将输出减少到10000条记录并立即结束。同样的,

SELECT * FROM table1 WHERE cond1 ORDER BY col1; 

SELECT * FROM table1 WHERE cond1 AND cond2 ORDER BY col1; 

似乎都要花很长时间。 CPU工作大约2秒钟,之后只有I/O。 CPU什么都不做,内存是免费的。

我在做什么错?

希望,这不是一个新手问题,我所要做的就是使用索引(但为什么?)。 Thx求助!

更具体的: 表结构:

0|url|TEXT|0||1 
    1|date|DATE|0||1 
    2|md5sum|TEXT|0||0 
    3|size|INTEGER|0||0 
    4|archive|TEXT|0||0 
    5|numScripts|INTEGER|0||0 
    6|numScriptBytes|INTEGER|0||0 
    7|numLinesBehaviour|INTEGER|0||0 
    8|state|TEXT|0||0 

声明:

SELECT * FROM t1 WHERE md5sum LIKE "00%" AND state=="okay" ORDER BY md5sum; 

还有的md5sum与国家之间没有任何联系。

我还没有创建任何索引。

我也忘了提及:只有当语句包含两个或多个字符串比较和排序时才会出现问题。所以

SELECT * FROM t1 WHERE md5sum LIKE "00%" AND state=="okay"; 

工程还行。

2更新: 一个明显的解决方法:

CREATE TABLE temp (url TEXT, date DATE, ... 
    INSERT INTO temp SELECT * FROM t1 WHERE state=="okay" AND md5sum LIKE "00%"; 
    SELECT * FROM temp ORDER BY md5sum; 

但是,该死的,必须有一个更简单的方法。

+1

这取决于条件cond2中写的是什么;涉及cond2索引的列是什么?如果你提供你的表格def,我们可以尝试更好的帮助你... – Marco

+2

你问的问题猜测'cond1'和'cond2'中的内容。关于这些条件的某些事情(可能与您在表格上创建的索引相结合)将查询从可优化的查询转换为不可查询的查询。请发布表结构和发送到数据库的实际SELECT语句。 –

+0

好吧,更具体一点:cond1和cond2之间没有逻辑连接。所以这些套是重叠的。还没有索引。 – user1030015

回答

0

我还没有创建任何索引。

这意味着DBMS将有权检查你的表的每一行只是进行选择。

ORDER BY md5sum;

这意味着DBMS必须对结果集进行排序(通常是N log(N)操作)。

添加索引可能会有所帮助,既可以通过更便宜地检查条件,也可以通过不必要的排序。(也许两者)

UPDATE(添加):

由于的md5sum是双方的选择条件和排序依据表达的一部分,你可以尝试通过增加一个假的词来排序表达愚弄queryplan发生器:

SELECT * from table1 
WHERE md5sum LIKE '00%' AND status = 'Ok' 
ORDER BY md5sum, status 
; 

没有保证,YMMV。

+0

但是等待:当它的工作没有排序时,选择不成问题。排序也很快(n * log(N)中的10000行应该不成问题)。但是,两者同时冻结了系统?必须有一些解释。 – user1030015

+0

那么,在你的情况下,选择的条件和排序的表达式是正交的:你不能同时拥有两者。哎呀,现在我发现你在选择中有像md5sum一样的丑陋。将md5sum放入某种索引将是第一步。 – wildplasser

+0

好的,谢谢。我去做。但我仍然不能相信MS在选择之后不能很快地进行排序。 – user1030015