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

.net dapper sqlite

我正在開發一個桌面應用程序,它使用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還是其他一些對像數據庫?

一般承認的答案

所以我終於找到了使用.NET在SQLite中進行高性能批量插入的技巧。這個技巧將插入性能提高了4.1倍!我的總節省時間從27秒增加到6.6秒。哇!

本文介紹了批量插入SQLite最快方法 。關鍵是重用相同的參數對象,但要為每個記錄插入,分配不同的值。 .NET構建所有這些DbParameter對象的時間確實增加了。例如,100k行和30列= 300萬個必須創建的參數對象。相反,創建和重用僅30個參數對像要快得多。

新表現:

  • 在.53秒內55,000行(19列)= 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的性能。


熱門答案

目前,我在事務中包裝插入以使它們更快(這是一個很好的改進)。

我在批量插入速度中看到的最大收穫是將插入分解成較小的塊。我確定,每個平台/架構/等等的塊有多小。我相信在我的測試中它接近1000左右。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因