我在sqlite中遇到一些奇怪的SELECT语句行为。有一张表有300万条记录。 E.g。
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什么都不做,内存是免费的。
我做错了什么?
希望,这不是一个新手问题,所有我要做的就是使用索引(但为什么?)。 求救!
更具体: 表结构:
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;
但是,该死的,必须有一个更简单的方法。
答案 0 :(得分:0)
我还没有创建任何索引。
这意味着DBMS必须检查表的每行才能进行选择。
ORDER BY md5sum;
这意味着DBMS必须对结果集进行排序(通常是N log(N)操作)。
添加索引可能有所帮助,无论是通过更便宜地检查您的状况,还是通过不需要排序。 (也许两者都有)
更新(已添加):
由于md5sum是选择条件和orderby表达式的一部分,你可能会试图通过在排序表达式中添加一个伪术语来欺骗查询计划生成器:
SELECT * from table1
WHERE md5sum LIKE '00%' AND status = 'Ok'
ORDER BY md5sum, status
;
无保证,YMMV。