Я знаю, что sqlite не очень хорошо работает с чрезвычайно большими файлами базы данных, даже когда они поддерживаются (на сайте sqlite был комментарий, в котором указано, что если вам нужны размеры файлов выше 1 ГБ, вы можете захотеть использовать предприятие rdbms. Не могу найти его больше, может быть связано с более старой версией sqlite).
Однако для моих целей я хотел бы получить представление о том, насколько это плохо, прежде чем я буду рассматривать другие решения.
Я говорю о файлах данных sqlite в диапазоне с несколькими гигабайтами, начиная с 2 ГБ. У кого-нибудь есть опыт? Любые советы/идеи?
Итак, я сделал несколько тестов с sqlite для очень больших файлов и сделал некоторые выводы (по крайней мере для моего конкретного приложения).
Тестирование включает в себя один файл sqlite с одной таблицей или несколькими таблицами. Каждая таблица имела около 8 столбцов, почти все целые числа и 4 индекса.
Идея заключалась в том, чтобы вставить достаточное количество данных, пока файлы sqlite не составят около 50 ГБ.
Отдельная таблица
Я попытался вставить несколько строк в файл sqlite только с одной таблицей. Когда файл был около 7 ГБ (извините, я не могу быть конкретным в отношении количества строк), вставки занимали слишком много времени. Я подсчитал, что мой тест на вставку всех моих данных займет около 24 часов, но он не завершился даже через 48 часов.
Это приводит меня к выводу, что одна, очень большая таблица sqlite будет иметь проблемы со вставками и, возможно, другие операции.
Я думаю, это не удивительно, поскольку таблица становится больше, вставка и обновление всех индексов занимает больше времени.
Несколько таблиц
Затем я попытался разделить данные по времени на несколько таблиц, по одной таблице в день. Данные для исходной 1 таблицы были разделены на ~ 700 таблиц.
У этой установки не было проблем с вставкой, она не занимала больше времени с течением времени, так как новая таблица была создана для каждого дня.
Вакуумные проблемы
Как указано i_like_caffeine, команда VACUUM является проблемой, тем больше файл sqlite. По мере того как будет выполнено больше вложений/удалений, фрагментация файла на диске будет ухудшаться, поэтому целью является периодическое VACUUM для оптимизации файла и восстановления файлового пространства.
Однако, как указано в документации, полная копия базы данных делается для того, чтобы сделать вакуум, потребовав очень много времени для завершения, Итак, чем меньше база данных, тем быстрее завершится эта операция.
Выводы
Для моего конкретного приложения я, вероятно, буду раскалывать данные по нескольким файлам db, по одному в день, чтобы получить максимум от производительности вакуума и скорости вставки/удаления.
Это усложняет запросы, но для меня это целесообразный компромисс, чтобы иметь возможность индексировать это много данных. Дополнительным преимуществом является то, что я могу просто удалить целый файл db, чтобы удалить данные за день (общая операция для моего приложения).
Мне, вероятно, придется контролировать размер таблицы для каждого файла, чтобы увидеть, когда скорость станет проблемой.
Слишком плохо, что не существует дополнительного метода вакуума, кроме автоматического вакуума. Я не могу использовать его, потому что моя цель для вакуума - дефрагментировать файл (файловое пространство не является большим делом), которого автоматический вакуум не делает. Фактически, документация утверждает, что это может сделать фрагментацию еще хуже, поэтому мне приходится прибегать к периодическому полному вакууму в файле.
Мы используем DBS 50 GB + на нашей платформе. никаких жалоб не работает. Убедитесь, что вы все делаете правильно! Вы используете предопределенные заявления? * SQLITE 3.7.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;
Надеюсь, это поможет другим, отлично работает здесь.
PRAGMA main.temp_store = MEMORY;
,
Я создал базы данных SQLite размером до 3,5 ГБ без заметных проблем с производительностью. Если я правильно помню, я думаю, что SQLite2 мог иметь некоторые более низкие пределы, но я не думаю, что SQLite3 имеет такие проблемы.
В соответствии с страницами SQLite Limits максимальный размер каждой страницы базы данных составляет 32K. Максимальные страницы в базе данных - 1024 ^ 3. Так по моей математике, которая достигает 32 терабайт как максимальный размер. Я думаю, вы попадете в пределы вашей файловой системы, прежде чем ударить SQLite!
Большая часть причин, по которым потребовалось более 48 часов, чтобы сделать ваши вставки, объясняется вашими индексами. Это невероятно быстрее:
1 - Отбросьте все индексы 2 - Сделайте все вставки 3 - Создание индексов снова
Кроме обычной рекомендации:
Из моего опыта работы с SQLite3 я узнал следующее:
Вопрос/комментарий.; -)
Я думаю, что основные жалобы на масштабирование sqlite:
У меня есть база данных SQLite объемом 7 ГБ. Для выполнения конкретного запроса с внутренним соединением требуется 2.6 Чтобы ускорить это, я попытался добавить индексы. В зависимости от того, какие индексы я добавил, иногда запрос опускался до 0,1 с, а иногда он увеличивался до 7 с. Я думаю, что проблема в моем случае заключалась в том, что если столбец сильно дублируется, то добавление индекса ухудшает производительность: (
В документации SQLite раньше указывалось, что практический размер файла базы данных составляет несколько десятков ГБ: с. В основном это связано с необходимостью SQLite "распределять битмап грязных страниц" всякий раз, когда вы начали транзакцию. Таким образом, 256 байт ОЗУ были необходимы для каждого МБ в базе данных. Вставка в DB файл объемом 50 ГБ потребует массивного (2 ^ 8) * (2 ^ 10) = 2 ^ 18 = 256 МБ ОЗУ.
Но по последним версиям SQLite это больше не требуется. Подробнее здесь.
2^18
на самом деле только 256 К.
У меня возникли проблемы с большими файлами sqlite при использовании команды вакуума.
Я еще не пробовал функцию auto_vacuum. Если вы планируете регулярно обновлять и удалять данные, то это стоит посмотреть.