Повысить производительность объемных вставок SQLite с использованием Dapper ORM
Я работаю над настольным приложением, которое использует SQLite для массового ввода десятков тысяч строк в базу данных SQLite. Я хотел бы помочь оптимизировать производительность объемной вставки. В настоящее время занимает до 50 секунд, чтобы вставить в базу данных 60 мегабайт.
-
какие параметры строки подключения можно использовать для улучшения
представление? Должен ли я изменить размер буфера? Возможно ли это с помощью
параметр строки подключения? Есть ли другая строка подключения
параметры для повышения производительности? Моя текущая строка подключения:
Источник данных = Batch.db; Версия = 3; Пул = Истина; Макс. пул Размер = 10; Синхронный = выкл. FailIfMissing = True; Режим журнала = Выкл.
-
Я использую Dapper ORM. (созданный ребятами из StackOverflow) Есть ли более быстрый способ для массовой вставки в Sqlite, в .net?
-
System.Data.Sqlite используется для вставки в SQLite. Как получить специальную скомпилированную версию sqlite, которая улучшает
представление? Является ли одна версия SQLite лучше другой? В данный момент
используя System.Data.SQLite от http://sqlite.phxsoftware.com
-
В настоящее время я переношу вставки внутри транзакции, чтобы сделать их быстрее (это сделало хорошее улучшение).
-
Я вставляю в одну таблицу за один раз в 17 таблиц. Могу ли я распараллелить это на разных потоках и сделать это быстрее?
Текущая производительность.
Это типично? Могу ли я лучше?
- 55 000 строк в таблицу с 19 столбцами: 2,25 с для вставки (24 тыс. вставки/сек)
- 10 000 строк в таблицу с 63 столбцами: 2,74 с для вставки (3,7 тыс./сек)
Мне нравится SQLite, но я хотел бы сделать это немного быстрее. В настоящее время сохранение моих объектов в XML файле с использованием сериализации XML происходит быстрее, чем сохранение базы данных SQLite, поэтому мой босс спрашивает: зачем переключиться на SQLite? Или я должен использовать MongoDB или какую-либо другую базу данных объектов?
Ответы
Ответ 1
Итак, я наконец нашел трюк для высокопроизводительных массивных вставок в SQLite, используя .NET. Этот трюк улучшил производительность вставки в 4,1 раза! Мое общее время сбережения составляло от 27 секунд до 6,6 секунды. Вау!
В этой статье объясняется самый быстрый способ делать массовые вставки в SQLite. Ключ используется для повторного использования одних и тех же объектов параметров, но для каждой вставки, назначая другое значение. Время, когда .NET берет на себя создание всех этих объектов DbParameter, действительно добавляет. Например, с 100k строк и 30 столбцов = 3 миллиона объектов параметров, которые необходимо создать. Вместо этого создание и повторное использование только 30 объектов параметров происходит намного быстрее.
Новая производительность:
-
55 000 строк (19 столбцов) в .53 секунды = 100 тыс. вставок/сек
internal const string PeakResultsInsert = @"INSERT INTO PeakResult values(@Id,@PeakID,@QuanPeakID,@ISTDRetentionTimeDiff)";
var command = cnn.CreateCommand();
command.CommandText = BatchConstants.PeakResultsInsert;
string[] parameterNames = new[]
{
"@Id",
"@PeakID",
"@QuanPeakID",
"@ISTDRetentionTimeDiff"
};
DbParameter[] parameters = parameterNames.Select(pn =>
{
DbParameter parameter = command.CreateParameter();
parameter.ParameterName = pn;
command.Parameters.Add(parameter);
return parameter;
}).ToArray();
foreach (var peakResult in peakResults)
{
parameters[0].Value = peakResult.Id;
parameters[1].Value = peakResult.PeakID;
parameters[2].Value = peakResult.QuanPeakID;
parameters[3].Value = peakResult.ISTDRetentionTimeDiff;
command.ExecuteNonQuery();
}
В конце концов, я не мог использовать Dapper для вставки в мои большие таблицы. (Для моих маленьких таблиц я все еще использую Dapper).
Заметьте, некоторые другие вещи, которые я нашел:
-
Я попытался использовать несколько потоков для вставки данных в одну базу данных, это не улучшилось. (не имеет значения)
-
Обновлено с System.Data.Sqlite 1.0.69 до 1.0.79. (не меняя производительность, которую я мог видеть)
-
Я не назначаю тип DbParameter, он, похоже, не имеет разницы в производительности.
-
Для чтения я не смог улучшить производительность Dapper.
Ответ 2
В настоящее время я обматываю вставки внутри транзакции, чтобы сделать их быстрее (это сделало хорошее улучшение).
Самый большой выигрыш, который я видел в режиме массовой вставки, заключался в том, чтобы разбить вставки на более мелкие куски. Я уверен, что размер пакета зависит от платформы/схемы и т.д. Я считаю, что во время моих испытаний это было около 1000 или около того.