Как оптимизировать индекс SQLite? - PullRequest
3 голосов
/ 18 марта 2011

У меня есть таблица t1 и два индекса:

create index if not exists timeindex on t1(time, "Bytes Received")
create index if not exists filenameindex on t1(filename)

Следующий запрос выполняется достаточно быстро:

select "Bytes Received" from t1 where time>="11:19:31.18" and time <= "11:19:36.18"

Но когда я добавляю дополнительное условие к оператору WHERE, запрос сильно замедляется

select "Bytes Received" 
    from t1 
    where time>="11:19:31.18" and time <= "11:19:36.18"
    and filename = "SE12.log"

Я пытался создать новый индекс t1(time, "Bytes Received", filename), но скорость выполнения не изменилась.

Как мне изменить индексы в таблице, чтобы ускорить запрос?

Ответы [ 2 ]

5 голосов
/ 18 марта 2011

Используйте BETWEEN и следующий индекс:

CREATE INDEX IF NOT EXISTS fntimeindex ON t1(filename ASC, time ASC);
SELECT "Bytes Received"
  FROM t1 INDEXED BY fntimeindex
  WHERE filename = 'SE12.log'
   AND time BETWEEN '11:19:31.18' AND '11:19:36.18';

Также обратите внимание, что в SQL строки заключаются в простые кавычки (двойные кавычки предназначены для имен таблиц, схем и столбцов).

1 голос
/ 13 сентября 2012

Ответ Бенуа верен в том, что BETWEEN сообщает Sqlite, что наступает диапазон, поэтому ему нужно только один раз выполнить поиск по индексу для обоих терминов в выражении AND (в противном случае он будет выполнять поиск по индексу дважды, один раз для левой руки).сторона, и один раз на право).Это сокращает количество записей, просмотренных в два раза.(Если вы запустите EXPLAIN QUERY PLAN в инструменте командной строки sqlite, это ясно покажет это.)

Однако планировщик запросов в Sqlite предпочитает использовать 1 индекс на таблицу.Чтобы обойти это, каноническое решение состоит в том, чтобы явно переписать запрос как серию ВЗАИМОДЕЙСТВУЮЩИХ подвыборов:

SELECT "Bytes Received" FROM t1 WHERE ROWID IN
(SELECT ROWID FROM t1 WHERE filename = 'SE12.log'
INTERSECT
SELECT ROWID FROM t1 WHERE time BETWEEN '11:19:31.18' AND '11:19:36.18'
)

Очевидно, что вы можете добавить дополнительные подвыборы для обработки дополнительных терминов.* Использование INDEXED BY не должно быть необходимым, поскольку это не «механизм подсказок», а жесткое требование (которое приведет к ошибке, если изменение схемы приведет к потере индекса - но, возможно, это то, что вам нужно.)

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