Медленное поведение Sqlite Select при попытке выбрать несколько строк - PullRequest
0 голосов
/ 13 июля 2020

У меня есть две таблицы в моей базе данных sqlite t1 и t2. t1 имеет два столбца a и b. t2 имеет один столбец, такой же, как в t1. Я построил индексы для каждого столбца в обеих таблицах. Я хочу выбрать все строки из таблицы t1, где t1.a существует в таблице t2. Итак, я написал запрос:

select t1.a, t1.b from t1 where t1.a in(select t2.a from t2) limit 10000000;

Я использую ограничение для выбора всех строк, а не первых 100.

Таблица t1 содержит 6000000 строк, таблица t2 100000 строк . Этот запрос выполняет 1400 мс.

Но когда я пытаюсь выбрать только t1.a с помощью этого запроса:

select t1.a from t1 where t1.a in(select t2.a from t2) limit 10000000;

, он занимает всего 86 мс.

Объясните план запроса:

SEARCH TABLE csv USING COVERING INDEX iin_idx (iin=?)
USING INDEX sqlite_autoindex_input_1 FOR IN-OPERATOR

Вопросы:

  1. Почему sqlite так себя ведет?
  2. Какая разница в выборе одного столбца или нескольких?
  3. Это возможно ли ускорить этот запрос?
  4. Почему sqlite использует автоиндекс вместо созданного?

Я хочу заполнить таблицу t1 155 000 000 строк, поэтому время запроса будет расти значительно.

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Думаю, что нашел решение! Я создал дополнительный индекс:

create index if not exists ab_b_idx on t1(a, b);

После этого выбор столбцов a и b выполняется так же быстро, как и выбор только столбца.

Объяснение этого поведения я нашел в документации Покрывающие индексы :

Если, однако, все столбцы, которые должны были быть извлечены из таблицы, уже доступны в самом индексе, SQLite будет использовать значения, содержащиеся в индексе и никогда не будет искать исходную строку таблицы. Это позволяет сэкономить один бинарный поиск для каждой строки и может привести к тому, что многие запросы будут выполняться вдвое быстрее.

Обновление: поиск по 100 000 000 строк в таблице t1 занял 550 мс.

0 голосов
/ 13 июля 2020

Одна из возможностей - кэширование диска . Чтение с диска происходит медленно, особенно если у вас есть жесткий диск (HDD), а не solid -state диск (SSD) При первом запуске запроса кеша "холодно" и данные должны быть загружены с диска в память. Во второй раз, когда вы запустите запрос, данные уже будут кэшированы в памяти и будут намного быстрее.

Попробуйте выполнить запросы несколько раз и посмотрите, не изменится ли производительность.

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