SQLite выполняет слишком много операций чтения с диска небольшого размера - PullRequest
0 голосов
/ 09 сентября 2018

Фон Я использую SQLite для хранения около 10 миллионов записей, где размер каждой записи составляет около 1 КБ. Я читаю эти данные порциями по 100 тысяч записей за раз, используя несколько параллельных потоков. Чтение и запись не идут параллельно, и все записи выполняются до начала чтения.

Проблема У меня слишком много операций чтения с диска. Каждую секунду происходит чтение около 3 Кб, и я читаю только данные по 30 Кб за эти 3 Кб (т.е. около 100 байт на чтение с диска). В результате я вижу ужасную производительность (чтение данных занимает около 30 минут)

Вопрос

  1. Существуют ли какие-либо настройки / прагмы SQlite, которые я могу использовать, чтобы избежать чтения диска небольшого размера?
  2. Существуют ли передовые практики для пакетного параллельного чтения в SQlite?
  3. Читает ли SQlite все результаты запроса за один раз? Или прочитать результаты в меньших кусках? Если последнее имеет место, то где оно частично выводится из запроса

Детали реализации Я использую SQlite с Java, и мое приложение работает на Linux. Библиотека JDBC: https://github.com/xerial/sqlite-jdbc (версия 3.20.1).

P.S Я уже построил необходимые индексы и проверил, что сканирование таблиц не выполняется (с помощью планировщика объяснения запросов)

1 Ответ

0 голосов
/ 09 сентября 2018

При поиске данных с индексом база данных сначала ищет значение в индексе, а затем переходит к соответствующей строке таблицы, чтобы прочитать все остальные столбцы.

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

Индексы ускоряют поиск, только если поиск сокращает количество строк. Если вы все равно будете читать все (или большинство) строк, сканирование таблицы будет намного быстрее.

Параллельное чтение будет более эффективным, только если диск действительно может обрабатывать дополнительный ввод / вывод. На вращающихся дисках дополнительные запросы только ухудшают ситуацию.

(SQLite пытается избежать сохранения временных результатов. Строки результатов вычисляются на лету (насколько это возможно), пока вы проходите через курсор.)

...