使用Dapper ORM提高SQLite批量插入的性能

9rnv2umw  于 2023-02-09  发布在  SQLite
关注(0)|答案(2)|浏览(217)

我正在开发一个桌面应用程序,它使用SQLite将数万行批量插入SQLite数据库。我希望您帮助我优化批量插入性能。目前,将60兆数据插入数据库需要50秒。

  • 我可以使用哪些连接字符串参数来提高性能?我应该更改缓冲区大小吗?是否可以通过连接字符串参数进行更改?是否有其他连接字符串参数可以提高性能?我当前的连接字符串是:

数据源=Batch.db;版本=3;合并=True;最大池大小=10;同步=关闭;如果缺失则失败=真;日志模式=关闭;

  • 我使用的是Dapper ORM。(由StackOverflow的人构建)有没有更快的方法来批量插入到Sqlite中?
  • System.Data.Sqlite用于向SQLite中进行插入。是否需要一个特殊编译版本的SQLite来提高性能?SQLite的一个版本是否优于另一个版本?当前正在使用http://sqlite.phxsoftware.com中的System.Data.SQLite
  • 目前,我在事务内 Package 插入以使它们更快(这是一个很好的改进)。
  • 我一次插入一个表,插入17个表。我能在不同的线程上并行执行这个操作并使它更快吗?
    **当前性能。**这是典型情况吗?我可以做得更好吗?
  • 将55,000行转换为19列的表格:2.25秒插入(24 k次插入/秒)
  • 将10,000行转换为63列的表格:插入时间为2.74秒(3.7k/秒)

我喜欢SQLite,但我希望它能更快一些。目前使用XML序列化将对象保存到XML文件比保存到SQLite数据库更快,所以我的老板问:为什么要切换到SQLite?或者我应该使用MongoDB,或者其他一些对象数据库?

pw136qt2

pw136qt21#

因此,我终于找到了一个技巧,在SQLite中使用.NET和System.Data.SQLite进行高性能批量插入。

  • 这个技巧提高了刀片性能的4.1倍!
  • 我的总保存时间从27秒降到了6. 6秒。哇!

本文介绍了fastest way to do bulk inserts into SQLitearchive.org link)。

  • 关键是重用相同的参数对象
  • 但是对于要插入的每个记录,分配不同的值。

.NET构造所有这些DbParameter对象所花费的时间实际上加起来。例如,100 k行和30列=必须创建300万个参数对象。相反,创建和重用30个参数对象要快得多。

更新新性能:

  • 55,000行(19列),0.53秒= 100 k插入/秒
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的性能。
5us2dqdw

5us2dqdw2#

目前,我在事务内 Package 插入以使它们更快(这是一个很好的改进)。
我所看到的在批量插入速度上最大的收获是将插入分成了更小的块。我确信,块的大小因平台/模式等而异。我相信在我的测试中,它接近1000左右。

相关问题