我正在开发一个桌面应用程序,它使用SQLite将数万行批量插入SQLite数据库。我想帮助优化批量插入性能。目前,将60兆位的数据插入数据库需要50秒。
我可以用什么连接字符串参数来改进 性能?我应该更改缓冲区大小吗?这可能是通过 连接字符串参数?是否还有其他连接字符串 参数提高性能?我当前的连接字符串是:
Data Source = Batch.db; Version = 3; Pooling = True; Max Pool Size = 10; Synchronous = off; FailIfMissing = True; Journal Mode = Off;
我正在使用Dapper ORM。 (由StackOverflow的人建造)在.net中是否有更快的方式批量插入Sqlite?
System.Data.Sqlite用于插入SQLite。如何获得改进的sqlite特殊编译版本 性能? SQLite的一个版本比另一个版本好吗?目前 使用http://sqlite.phxsoftware.com
目前,我正在将事件中的插入包装起来以使它们更快(这是一个很好的改进)。
我一次在一张桌子中插入17张桌子。我可以在不同的线程上并行化这个并加快速度吗?
目前的表现。 这是典型的吗?我能做得更好吗?
我喜欢SQLite,但我希望能让它快一点。目前使用XML序列化将我的对象保存到XML文件比保存到SQLite数据库要快,所以我的老板问:为什么要切换到SQLite?或者我应该使用MongoDB还是其他一些对象数据库?
答案 0 :(得分:14)
所以我终于找到了使用.NET在SQLite中进行高性能批量插入的技巧。这个技巧将插入性能提高了4.1倍!我的总节省时间从27秒增加到6.6秒。哇!
本文解释了fastest way to do bulk inserts into SQLite。关键是重用相同的参数对象,但要为每个记录插入,分配不同的值。 .NET构建所有这些DbParameter对象的时间确实增加了。例如,100k行和30列= 300万个必须创建的参数对象。相反,创建和重用仅30个参数对象要快得多。
新表现:
55,000行(19列),.53秒= 100k插入/秒
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分配一个Type,但它似乎没有产生性能差异。
对于读物,我无法改善Dapper的表现。
答案 1 :(得分:0)
目前,我在事务中包装插入来制作它们 更快(这是一个很好的改进)。
我在批量插入速度中看到的最大收获是将插入分成更小的块。我确定,每个平台/架构/等等的块有多小。我相信在我的测试中,它接近1000左右。