Каковы характеристики производительности sqlite с очень большими файлами базы данных?

Я знаю, что sqlite не очень хорошо работает с очень большими файлами баз данных, даже если они поддерживаются (на веб-сайте sqlite был комментарий, в котором говорилось, что если вам нужны файлы размером более 1 ГБ, вы можете рассмотреть возможность использования корпоративных rdbms. больше не может найти, может быть связано с более старой версией sqlite).

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

Я говорю о файлах данных sqlite в диапазоне нескольких гигабайт, начиная с 2 ГБ. У кого-нибудь есть опыт работы с этим? Любые советы / идеи?

9 ответов

Решение

Поэтому я провел несколько тестов с sqlite для очень больших файлов и пришел к некоторым выводам (по крайней мере, для моего конкретного приложения).

В тестах используется один файл sqlite с одной или несколькими таблицами. Каждая таблица имела около 8 столбцов, почти все целые числа и 4 индекса.

Идея заключалась в том, чтобы вставить достаточно данных, пока размер файлов sqlite не достигнет 50 ГБ.

Одноместный стол

Я попытался вставить несколько строк в файл sqlite только с одной таблицей. Когда размер файла составлял около 7 ГБ (извините, я не могу точно сказать, сколько строк) вставки занимали слишком много времени. Я подсчитал, что мой тест для вставки всех моих данных займет около 24 часов, но он не завершился даже после 48 часов.

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

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

Несколько столов

Затем я попытался разделить данные по времени на несколько таблиц, по одной таблице в день. Данные для исходной таблицы 1 были разбиты на ~700 таблиц.

У этой установки не было проблем с вставкой, она не занимала больше времени, так как новая таблица создавалась для каждого дня.

Проблемы с вакуумом

Как указано в i_like_caffeine, команда VACUUM является проблемой, когда файл sqlite больше. По мере выполнения большего количества операций вставки / удаления фрагментация файла на диске будет ухудшаться, поэтому цель состоит в том, чтобы периодически VACUUM оптимизировать файл и восстанавливать файловое пространство.

Однако, как указано в документации, полная копия базы данных создается для создания вакуума, на завершение которого уходит очень много времени. Таким образом, чем меньше база данных, тем быстрее завершится эта операция.

Выводы

Для моего конкретного приложения я, вероятно, буду разбивать данные по нескольким файлам БД, по одному в день, чтобы получить как максимальную производительность, так и скорость вставки / удаления.

Это усложняет запросы, но для меня целесообразно индексировать такое количество данных. Дополнительным преимуществом является то, что я могу просто удалить весь файл базы данных, чтобы отбросить данные за день (обычная операция для моего приложения).

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

Жаль, что, похоже, нет другого метода добавочного вакуума, кроме автоматического вакуума. Я не могу использовать его, потому что моя цель для вакуума - дефрагментировать файл (файловое пространство не имеет большого значения), чего не делает автоматический вакуум. На самом деле документация утверждает, что это может ухудшить фрагментацию, поэтому мне приходится периодически прибегать к созданию полного вакуума в файле.

Мы используем DBS 50 ГБ + на нашей платформе. без жалоб работает отлично. Убедитесь, что вы все делаете правильно! Вы используете предопределенные заявления? *SQLITE 3.7.3

  1. операции
  2. Предварительно сделанные заявления
  3. Примените эти настройки (сразу после создания БД)

    PRAGMA main.page_size = 4096;
    PRAGMA main.cache_size=10000;
    PRAGMA main.locking_mode=EXCLUSIVE;
    PRAGMA main.synchronous=NORMAL;
    PRAGMA main.journal_mode=WAL;
    PRAGMA main.cache_size=5000;
    

Надеюсь, что это поможет другим, отлично работает здесь

Я создал базы данных SQLite размером до 3,5 ГБ без каких-либо заметных проблем с производительностью. Если я правильно помню, я думаю, что SQLite2 мог иметь некоторые более низкие пределы, но я не думаю, что SQLite3 имеет такие проблемы.

Согласно странице ограничений SQLite, максимальный размер каждой страницы базы данных составляет 32 КБ. А максимальное количество страниц в базе данных составляет 1024^3. Так что по моей математике получается 32 терабайта как максимальный размер. Я думаю, что вы достигнете пределов своей файловой системы, прежде чем достигнете ограничений SQLite!

Во многом причина того, что на вставку ушло> 48 часов, связана с вашими индексами. Это невероятно быстрее:

1 - удалить все индексы 2 - сделать все вставки 3 - снова создать индексы

Помимо обычной рекомендации:

  1. Падение индекса для массовой вставки.
  2. Пакетные вставки / обновления в больших транзакциях.
  3. Настройте свой буферный кеш / отключите журнал /w PRAGMA.
  4. Используйте 64-битную машину (чтобы иметь возможность использовать много кеша ™).
  5. [добавлено в июле 2014 г.] Используйте общее табличное выражение (CTE) вместо выполнения нескольких SQL-запросов! Требуется версия SQLite3.8.3.

Из моего опыта работы с SQLite3 я узнал следующее:

  1. Для максимальной скорости вставки не используйте схему с какими-либо ограничениями на столбцы. (Изменить таблицу позже по мере необходимости Вы не можете добавлять ограничения с помощью ALTER TABLE).
  2. Оптимизируйте свою схему, чтобы хранить то, что вам нужно. Иногда это означает разрушение таблиц и / или даже сжатие / преобразование ваших данных перед вставкой в ​​базу данных. Отличным примером является хранение IP-адресов в виде (длинных) целых чисел.
  3. Одна таблица на файл базы данных - чтобы минимизировать конфликт блокировки. (Используйте ATTACH DATABASE, если вы хотите иметь один объект подключения.
  4. SQLite может хранить различные типы данных в одном столбце (динамическая типизация), используйте это в своих интересах.

Вопрос / комментарий приветствуется.;-)

У меня есть база данных SQLite 7 ГБ. Для выполнения определенного запроса с внутренним объединением требуется 2,6 с. Чтобы ускорить это, я попытался добавить индексы. В зависимости от того, какие индексы я добавил, иногда количество запросов уменьшалось до 0,1 с, а иногда до 7 с. Я думаю, что проблема в моем случае заключалась в том, что если столбец сильно дублируется, то добавление индекса снижает производительность:(

В документации SQLite существовало утверждение, что практический предел размера файла базы данных составляет несколько десятков ГБ: с. В основном это было связано с необходимостью SQLite "выделять битые карты грязных страниц" всякий раз, когда вы начинали транзакцию. Таким образом, 256 байт оперативной памяти требовалось для каждого МБ в базе данных. Вставка в DB-файл объемом 50 ГБ потребует огромного (2^8)*(2^10)=2^18=256 МБ ОЗУ.

Но с недавних версий SQLite это больше не требуется. Узнайте больше здесь.

Я думаю, что основные жалобы на масштабирование sqlite:

  1. Единый процесс записи.
  2. Нет зеркалирования.
  3. Нет тиражирования.

У меня возникли проблемы с большими файлами sqlite при использовании команды вакуума.

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

Другие вопросы по тегам