SQLite: каковы практические ограничения? - PullRequest
7 голосов
/ 12 марта 2012

Прежде чем пометить этот вопрос как дубликат, ПОЖАЛУЙСТА, СЛЫШИТЕ МНЕ !!
Я уже прочитал заданные здесь вопросы о том, как улучшить производительность, например. просто упомянуть несколько Улучшение производительности SQLite по INSERT-в-секунду? и Каковы характеристики производительности sqlite с очень большими файлами базы данных?

Я пытаюсь заставить sqlite работать с размером файла базы данных 5 гигабайт. Наоборот, есть люди, которые утверждают, что sqlite работает для них «отлично», даже если размер базы данных достигает 160 ГБ. Я сам не пробовал, но, исходя из заданных вопросов, я полагаю, что все тесты могут быть выполнены только с таблицей в базе данных.

Я использую базу данных с
- 20 или около того таблиц
- Половина таблиц имеет более 15 столбцов
- Каждая из этих 15-или около-столбцов таблиц имеет 6/7 столбцов внешнего ключа - Некоторые из этих таблиц уже выросли до 27 миллионов записей в месяц

Машина для разработки, которую я использую, представляет собой четырехъядерный процессор с частотой 3 ГГц и 4 гигабайтами оперативной памяти, и все же для запроса row_count в этих больших таблицах требуется более 3 минут.

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

Так что мои вопросы
а) Я использую неверную базу данных для работы?
б) Что вы думаете, где я иду не так?
c) Я еще не добавил индексы для внешних ключей, но если запрос количества строк занимает четыре минуты, как мне помогают индексы внешних ключей?

EDIT Чтобы предоставить больше информации, хотя никто не просил об этом :) Я использую SQLite версии 3.7.9 с system.data.sqlite.dll версии 1.0.77.0

EDIT2: Я думаю, что я отличаюсь от парней из 160 гигов в том, что они могут выбрать отдельную запись или небольшой диапазон записей. Но мне нужно загрузить все 27 миллионов строк в моей таблице, соединить их с другими таблицами, сгруппировать записи по запросу пользователя и вернуть результаты. Любая информация о том, как лучше оптимизировать базу данных для таких результатов.

Я не могу кэшировать результаты предыдущего запроса, так как в моем случае это не имеет смысла. Вероятность попадания в кеш будет довольно низкой.

Ответы [ 3 ]

5 голосов
/ 12 марта 2012

Здесь есть над чем подумать, но мой первый совет - не принимать статистику производительности других пользователей за чистую монету. Производительность базы данных зависит от многих факторов, включая структуру вашей базы данных, сложность ваших запросов, какие индексы вы определили (или нет), а зачастую и просто огромное количество данных в них. Множество сообщаемых показателей производительности происходит из-за большого количества проб и ошибок и / или соответствия базы данных выполняемой работе. Иными словами, производительность, которую вы получите от любой СУБД, не может сравниться с производительностью другого приложения, если ваши наборы данных и структуры практически не идентичны - они, безусловно, являются руководством и, возможно, идеалом, к которому нужно стремиться. , но вы не обязательно получите безумную производительность "из коробки".

В качестве отправной точки я бы начал индексировать данные этих действительно больших таблиц (судя по комментариям, что вы их получили) и посмотрел, что произойдет. Конечно, подсчет, занимающий четыре минуты, довольно длинный, но не останавливайтесь на этом. Добавьте некоторые индексы, измените их, спросите, храните ли вы данные, которые вам не нужно хранить, и посмотрите на другие запросы к базе данных, а не только на запрос подсчета, чтобы оценить производительность. Найдите другие приложения и публикации в блогах, которые используют SQLite для большого количества строк, и посмотрите, что они сделали для его решения (что может включать в себя изменение баз данных). По сути, попробуйте что-нибудь, а затем принять решение. Не позволяйте первоначальному страху остановить вас, думая, что вы идете по неверному пути. Может быть, да, а может и нет, но не останавливайтесь на вопросе COUNT. В любом случае, 27 миллионов записей в таблице - тонна дерьма.

Наконец, один конкретный совет заключается в следующем: в SQLite не разбивайте базу данных на несколько файлов - я не вижу в этом никакой полезности, потому что тогда вам придется выполнять много дополнительных запросов. работать, а затем вручную объединить ваши отдельные таблицы после возвращения результатов из нескольких запросов. Это переосмысление того, что СУБД делает для вас, и это безумная идея. Вы не собираетесь каким-то образом придумывать способ сделать объединение быстрее, чем создатели системы RDBMS - вы определенно будете тратить время там.

0 голосов
/ 12 мая 2016

Если у вас есть 50 МБ или более дБ, непосредственно развернутых на стороне клиента, это означает, что вы делаете что-то не так. Попробуйте перенести на сервер, сохранив ключ - важное значение на клиенте. (только ссылки) У вас не будет реального времени, но, по крайней мере, оно даст соответствующее решение. «Серверная сторона» - это ответ на ваш вопрос, то есть если вы отбрасываете или оптимизируете требования в реальном времени, потому что это то, что у вас есть (на основе вашего описания). В любом случае. SQLite может справиться практически с чем угодно, но, исходя из личного опыта, просто постарайтесь максимально упростить ситуацию, даже за счет результата в реальном времени.

0 голосов
/ 07 октября 2014

select count (*) в SQLite всегда будет медленнее по сравнению с другими DMBS, потому что он выполняет сканирование таблицы для этого конкретного запроса. У него нет таблицы статистики, чтобы выручить. Это не означает, что запросы вашего приложения будут медленными. Вам нужно проверить свои запросы, чтобы действительно сказать, чего вы можете ожидать.

Некоторые общие рекомендации. Индексирование является обязательным условием, поскольку перемещение по подмножеству данных в двоичном дереве намного быстрее, чем обход всей таблицы, когда речь идет об огромных размерах. Чтобы увеличить время загрузки, вы должны отсортировать данные по уникальному индексу, а если у вас нет уникального индекса, то самый большой индекс. Если вы можете сбросить индексы перед загрузкой и вернуть их после, это будет быстрее. Если эти методы не могли соответствовать вашим рабочим параметрам и параметрам SLA, то пришло время выполнить горизонтальное разбиение и использовать «присоединение» для охвата необходимого диапазона данных. SQLite может поддерживать до 10 подключений. Я знаю, что некоторые говорят, что разделение - это работа инструмента, а не разработчиков, но когда вы сталкиваетесь с физическими ограничениями, вы должны засучить рукава или, возможно, выбрать коммерческий инструмент, который делает это под прикрытием.

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