Альтернатива SQLite с одновременной записью (Delphi) - PullRequest
6 голосов
/ 13 февраля 2012

(с использованием Delphi 2010 + последний SQLite в режиме WAL)

Я использую DISQLite (Delphi-порт SQLite) с моим многопоточным клиентским приложением (еще не выпущено, поэтому я могу изменить механизм БД, если у меня действительно есть в)

Мой профилировщик ясно говорит, что это глупое решение, я разобрал это до 2-3 очень простых операторов SQL, которые вылетают при выполнении в однопоточном приложении, но из-за блокировки / ожидания потоков (SQLite действительно плохо работает с несколько потоков пытаются писать одновременно)

Я приложил все усилия, чтобы оптимизировать свой код / ​​избежать узких мест, но после нескольких недель напряженной работы, я задаюсь вопросом, не проще ли просто сбросить SQLite и выбрать другой механизм БД (?)

Мои требования:

  1. ACID
  2. Очень хорошая поддержка одновременного чтения / записи (уровень записи)
  3. (Очень) Быстрый и стабильный движок БД
  4. B-Tree
  5. Поддержка Delphi 2010

Я использую только базовые команды INSERT / UPDATE / DELETE с индексами, ничего особенного. Так что мои требования к SQL относительно просты (мне не нужны соединения или другие "более продвинутые" функции SQL).

Я также открыт для решений NQL, если они поддерживают требования, указанные выше.

Мои исследования привели к созданию Berkley DB, который, если я правильно понял, является модифицированной версией SQLite с поддержкой одновременной записи, но проблема в том, что это не совсем для Delphi.

Я также читал о Киотском Кабинете, но опять же, нет поддержки delphi: (

Любое предложение будет более чем приветствоваться,

Спасибо!

Ответы [ 6 ]

3 голосов
/ 14 февраля 2012

Какова скорость вашего приложения, если:

  • Вы используете только одно соединение с БД для всех своих потоков;
  • Вы защищаете доступ к соединению с БД с помощью глобальной критической секции.

Затем вы можете попробовать нашу статическую привязку Sqlite3 , которая была скомпилирована без мьютекса потока:

#define SQLITE_THREADSAFE 2
//  assuming multi-thread safety is made by caller - in our framework, there is
// only one thread using the database connection at the same time, but there could
// be multiple database connection at the same time (previous was 0 could be unsafe)
#define SQLITE_OMIT_SHARED_CACHE 1
// no need of shared cache in a threadsafe calling model

Мы используем такую ​​модель в нашей среде ORM mORMot, и,связан с четырьмя уровнями кэша:

  • Кэш операторов для повторного использования операторов SQL и связанных параметров на лету;
  • Глобальный кэш результатов JSON на уровне базы данных, который сбрасывается глобальнона любой INSERT / UPDATE;
  • настроенный кэш записей на уровне CRUD / RESTful для указанных таблиц или записей на стороне сервера;
  • настроенный кэш записей на уровне CRUD / RESTful для указанных таблиц илизаписи на стороне клиента.

Результирующая производительность совсем не плохая - она ​​хорошо масштабируется при многопоточном доступе, даже с глобальным критическим разделом.Конечно, SQlite3 не был разработан для масштабирования так же хорошо, как Oracle!Но я использовал SQlite в реальных приложениях с большим количеством клиентов.Вы можете рассмотреть возможность использования FireBird , который имеет более сложную (и настроенную) архитектуру для клиент-сервер.

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

SQLite3 очень быстро для такого добавления (даже больше с подготовленным оператором INSERT со связанными параметрами), но медленно для отдельных добавлений, потому что он должензаблокировать весь файл с помощью низкоуровневого API, что чертовски медленно.Чтобы сделать его ACID, убедитесь, что коммит всегда обрабатывается.Фактически, другие механизмы DB достигают хорошей параллельной скорости с подобным процессом, скрытым в фоновом режиме.Ожидается, что метод записи по умолчанию в SQLite3 будет таким, чтобы обеспечить доступ к одному и тому же файлу из нескольких процессов, но в приложении «клиент-сервер» вы можете полагаться только на то, что вы будете единственным, кто имеет доступ кФайл базы данных SQLite3, поэтому он будет в безопасности.

2 голосов
/ 13 февраля 2012

Может ли что-нибудь помочь встроенная версия Firebird DB?

Страница загрузок FirbirdSQL.org

Я успешно использовал это в прошлом.

1 голос
/ 13 февраля 2012

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

0 голосов
/ 08 марта 2012

FWIW, я наконец-то решил придерживаться DISQLite вместе с этим «уродливым», хакерским решением:

  • Внесены некоторые (не столь незначительные) изменения, чтобы максимально сократить запись в БД внутри потоков (требуется две вставки БД в каждый поток)

  • Когда мне абсолютно приходилось что-то записывать в БД при работе внутри потоков, я брал параметры запроса SQL и записывал их в специальную папку (запись в файлы очень быстро), т.е.

C: \ My-проекта \ очереди-SQL \ insert_SOME-GUID.txt

Каждый файл будет выглядеть так:

Param1 | Param2 | Param3 | Param4 |

  • Как только я закончил с потоками (или если мое приложение зависло), я вызвал подпрограмму, которая просканировала эту папку, извлекла параметры SQL и запустила их, используя подготовленные операторы (заключенные в транзакцию).

  • Любой файл, содержащий, скажем, менее 4 параметров, будет считаться поврежденным и будет пропущен.

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

Я просто хотел поблагодарить всех за помощь, из-за нехватки времени я не могу переключиться на другой движок БД, по крайней мере, для этого проекта.

0 голосов
/ 14 февраля 2012

NexusDB может сделать все это, и Embedded Version бесплатна .Он поддерживает Delphi как первоклассного гражданина.

0 голосов
/ 13 февраля 2012

Это моя точка зрения:

Абсолютная база данных - хорошая альтернатива.

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