Проблема с производительностью ORDER BY + AND в sqlite - PullRequest
1 голос
/ 04 ноября 2011

Я испытываю странное поведение с инструкциями SELECT в sqlite.Есть одна таблица с 3 миллионами записей.Например,

    SELECT * FROM table1 WHERE cond1;

уменьшает вывод до 10000 записей и мгновенно завершает работу.То же самое с

    SELECT * FROM table1 WHERE cond1 ORDER BY col1;

Но

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

, кажется, вечно.Процессор работает около 2 секунд и после этого остается только ввод-вывод.Процессор ничего не делает, память свободна.

Что я делаю не так?

Надеюсь, это не вопрос новичка, и все, что мне нужно сделать, - это использовать индекс (но почему?).Спасибо за помощь!

Более конкретно: структура таблицы:

    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 Ответ

0 голосов
/ 05 ноября 2011

Я не создал ни одного индекса.

Это означает, что СУБД должна будет проверять каждую строку вашей таблицы только для того, чтобы сделать выбор.

ЗАКАЗАТЬ по md5sum;

Это означает, что СУБД должна отсортировать (обычно операция N log (N)) набор результатов.

Добавление индексов может помочь, либо сделав проверку вашего состояния более дешевой, либо сделав сортировку ненужной. (а может и то и другое)

ОБНОВЛЕНИЕ (добавлено):

Поскольку md5sum является частью условия выбора и выражения orderby, вы можете попытаться обмануть генератор плана запросов, добавив фиктивный термин к выражению сортировки:

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

Нет гарантий, YMMV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...