2012-02-13 2 views
6

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

Я использую DISQLite (Delphi порт SQLite) с моим многопоточным приложением клиента (все же быть освобожден, так что я могу изменить двигатель DB, если я действительно должны)

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

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

Моих требований являются:

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

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

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

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

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

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

Благодаря

+0

Я не уверен в привязках к Delphi, но вы можете взглянуть на http://en.wikipedia.org/wiki/Berkeley_DB (имеет привязки для большинства остальных) –

+1

@JoachimIsaksson: Спасибо, да, я посмотрел в BDB в Википедии я нашел это: http://www.demonak.com/delphi/berkeleydb.en.shtml и «AnyDAC для поддержки DB Delphi Berkeley», но я не уверен, что это то, что я хочу (не упомянуть о стоимости лицензии ... :() – TheDude

+0

Я использую его для использования с открытым исходным кодом, и я не видел в вашем вопросе, что вы указали открытый исходный код или нет, но да, я определенно мог бы видеть, что затраты на лицензирование Oracle являются проблемой. для open source в той же ситуации, хотя :) –

ответ

0

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

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

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

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

Каждый файл будет выглядеть следующим образом:

Param1 | Param2 | Param3 | Param4 |

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

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

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

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

0

Это моя точка:

Absolute Database является хорошей альтернативой.

+0

Спасибо! Я фактически отказался от Absolute до DISQLite прошлым летом (использовал его в течение 6 лет). AFAIK, с AbsoluteDB, у вас либо есть одновременная поддержка записи, либо ACIDity, но вы не можете иметь оба – TheDude

+0

. Добро пожаловать. Какая версия, пожалуйста? – menjaraz

+0

Я использовал оба v5 и v6 (оба для D2010 и D7) – TheDude

2

Возможно, что-то вроде встроенной версии Firebird DB?

FirbirdSQL.org Downloads Page

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

+0

Действительно, версия 2.5 также является хорошим выбором – menjaraz

+0

Интересно ... FireFird определенно кажется хорошим выбором. Я изучу его (интересно, как он сравнивается с точки зрения скорости с SQLite ...) – TheDude

+0

@Gdhami: Я использовал оба варианта, и хотя встроенная версия FB немного тяжелее, чем SQLite, она имеет все особенности полномасштабной версии FB. Разумеется, за исключением отдельных пользователей и многопользовательских пользователей. Как только двигатель загрузится в память, я бы ожидал, что разница в скорости будет минимальной. –

1

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

+0

Спасибо, да, я действительно сделал что-то вроде этого (не добавлял их, хотя: это означало бы потерю ACIDity, так как я использую WAL) ... он * сделал * помощь - много, но мой профилировщик говорит о некоторых * * очень простые SQL-запросы занимают 20 и более секунд, чтобы выполнять многопоточность, а в однопоточном режиме - менее 0,01 мс! (это не типично, но этого достаточно для замедления всей операции) – TheDude

+0

Я также должен упомянуть, что я использую простые SQL-запросы с индексами и т. д. – TheDude

+0

Вы уверены, что не делали что-то не так? Такая большая разница между этими же запросами очень странная и маловероятная. Еще одним решением было бы прекратить использование WAL. – Linas

0

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

+0

Спасибо, я посмотрю! – TheDude

3

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

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

Тогда вы можете попробовать наш Sqlite3 static binding, который был скомпилирован без резьбы мьютекс:

#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 

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

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

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

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

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

+0

спасибо, читайте, что производительность в порядке с WAL, моя проблема на самом деле связана с ** одновременным написанием **, что, к сожалению, SQLite не поддерживает :( – TheDude

+0

Что касается производительности моего приложения, то это очень ** медленно с одним потоком ,Я стараюсь использовать критические разделы только там, где это необходимо (один раз в начале и один раз в конце каждого потока - только для записи в БД). Много хорошего в твоем посте, я посмотрю, спасибо! – TheDude

+0

О создании писем быстрее, вы можете сгруппировать свои записи в транзакцию, тогда это будет * намного быстрее. Это то, что я использую в http://blog.synopse.info/post/2011/06/03/BATCH-sequences-for-adding/updating/deleting-records, и вы можете расширить эту концепцию несколькими клиентами: на сервере вы перегруппируете свои записи в общую транзакцию, которая должна быть зафиксирована после периода ожидания (например, одна секунда). SQLite3 очень быстро подходит для такого добавления (еще больше с подготовленным оператором INSERT со связанными параметрами), но медленным для отдельных дополнений. Это то, что делает другая клиентская база данных. –