Dot-Net

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

  • February 21, 2016

我正在開發一個桌面應用程序,它使用 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 個參數對像要快得多。

新性能:

  • 55,000 行(19 列)在 0.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 分配類型,無論哪種方式似乎都不會產生性能差異。
  • 對於讀取,我無法提高 Dapper 的性能。

引用自:https://stackoverflow.com/questions/9006604