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

时间:2012-01-25 16:52:46

标签: .net sqlite dapper

我正在开发一个桌面应用程序,它使用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

  • 中的System.Data.SQLite
  • 目前,我正在将事件中的插入包装起来以使它们更快(这是一个很好的改进)。

  • 我一次在一张桌子中插入17张桌子。我可以在不同的线程上并行化这个并加快速度吗?

目前的表现。 这是典型的吗?我能做得更好吗?

  • 55,000行进入表格,19列:插入2.25秒(24k插入/秒)
  • 10,000行进入表格,63列:插入2.74秒(3.7k /秒)

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

2 个答案:

答案 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左右。