У меня есть простой запрос, такой как
SELECT * FROM "mytable" where col1="foo"
, который разрешается примерно за 0,5 секунды (приблизительно 100 результатов приблизительно из 100 000 строк файла базы данных объемом 700 МБ)
Однако,как только я добавляю ORDER BY
, это занимает 120 секунд.
SELECT * FROM "mytable" where col1="foo" ORDER BY col2
Даже когда я ограничиваю результат следующим образом
SELECT * FROM (SELECT * FROM "mytable" where col1="foo" LIMIT 1) ORDER BY col2
, это занимает 120 секунд, хотя сортировать буквально нечего.
Единственное исключение - если я сортирую с ORDER BY rowid
(вместо ORDER BY col2
) или когда я делаю это так (0,5 секунды):
SELECT * FROM "mytable" WHERE rowid IN (SELECT rowid FROM "mytable" WHERE col1="foo") ORDER BY col2
I VACUUM
'редактировал базу данных, и я проверил целостность базы данных (хорошо), и эта проблема сохраняется.Я использую версию SQLite: 3.7.7.1, замедления появляются как в phpLITEadmin, так и в моем коде PHP.
Редактировать
EXPLAIN QUERY PLAN SELECT * FROM "mytable" WHERE col1="foo"
selectid|order|from|detail
0| 0| 0|SCAN TABLE mytable (~11345 rows)
EXPLAIN QUERY PLAN SELECT * FROM "mytable" WHERE col1="foo" ORDER BY col2
selectid|order|from|detail
0| 0| 0|SEARCH TABLE mytable USING AUTOMATIC COVERING INDEX (col1=?) (~7 rows)
0| 0| 0|USE TEMP B-TREE FOR ORDER BY
Решение
ОК, кажется, мы нашли решение: CREATE INDEX col1_idx ON "mytable" (col1)
необходимо по какой-то загадочной причине.Создание индекса для col2 (столбец, по которому нужно отсортировать) не имеет значения (120 секунд для сортировки с индексом для col2 или без него).Для меня это похоже на ошибку SQLite, потому что результат запроса без индексированного столбца col1 быстрый (0,5 секунды), а сортировка одной неиндексированной строки (= вообще не сортировка) не должна занимать 120 секунд.Даже сортировка всей таблицы SELECT * FROM "mytable" ORDER BY col2
занимает SQLite всего за 7 секунд.
Также интересно: CREATE INDEX для col1 и col2 занял всего 1,5 секунды.Таким образом, даже если предположить, что причиной этого замедления является то, что SQLite автоматически создает временный индекс для запроса, он все равно не объясняет, почему SQLite так долго сортируется.