Я только начал проводить некоторые тесты производительности моего проекта Fluent NHibernate / SQLite и испытываю серьезные задержки при фиксации базы данных. Серьезно, я имею в виду 20-30 секунд, чтобы зафиксировать 30 КБ данных!
Эта задержка, похоже, ухудшается по мере роста базы данных. Когда файл БД SQLite пуст, коммиты происходят почти мгновенно, но когда он увеличивается до 10 мегабайт, я вижу эти огромные задержки.
База данных содержит 16 таблиц, в среднем по 10 столбцов каждая.
Одной из возможных проблем является то, что я храню дюжину или около того IList<float>
членов, но обычно они состоят всего из 200 элементов. Но это недавнее добавление к автоматическому сопоставлению Fluent NHibernate, в котором каждое число с плавающей точкой хранится в одной строке таблицы, так что, возможно, это потенциальная проблема.
Любые предложения о том, как отследить это? Я подозреваю, что SQLite является виновником, но, может быть, это NHibernate?
У меня нет опыта работы с профилировщиками, но я думаю получить его. Мне известно о NHibernate Profiler - есть ли рекомендации для профилировщиков, которые хорошо работают с SQLite?
Редактировать
Некоторое дополнительное тестирование показывает, что замедление вызывает не размер базы данных - это зависит от того, сколько сохранений я сделал с момента запуска моей программы. Время фиксации для первого сохранения составляет около 300 мс, а к 50-му сохранению составляет более 1000 мс.
Я все время держу одну открытую сессию - может, мне нужна какая-то явная логика Flush?
Кроме того, я скачал NHibernate Profiler. Это дало мне предупреждение о «большом количестве отдельных записей» для моих участников IList. В описании оповещения предлагалось включить пакетную обработку, но, насколько я могу судить, SQLite не поддерживает это.
Также упоминается поддержка Multiquery, поэтому я собираюсь прочитать об этом.
/ Edit
Вот метод, который сохраняет данные - это просто вызов SaveOrUpdate и Commit, если вы игнорируете всю обработку ошибок и ведение журнала отладки.
public static void SaveMeasurement(object measurement)
{
// Get the application's database session
var session = GetSession();
using (var transaction = session.BeginTransaction())
{
session.Save(measurement);
transaction.Commit();
}
}