0

我問了一個question這是我如何更快地運行任務,但沒有任何答案適用於我。我有以下代碼將1500條記錄插入數據庫,但問題是需要大約4秒。我用async/await,並行循環和AddRange,我也保存更改自動檢測和驗證保存但沒有任何影響。我的代碼是這樣的:以更快的速度運行插入數據庫任務

async void button7_Click(object sender, EventArgs e) 
{ 
    var task = await Task.Run(() => 
    { 
     Random rnd = new Random(); 
     for (int i = 0; i <= 1500; i++) 
     { 
      db.Tbls.Add(new Tbl() 
      { 
       Name = "User" + i + 1, 
       Num = rnd.Next(10, i + 10)/10 
      }); 
     } 

     db.SaveChanges(); 
     return db.Tbls.Count(); 

    }); 
} 

而且具有的AddRange:

async void button7_Click(object sender, EventArgs e) 
{ 
    var task = await Task.Run(() => 
    { 
     Random rnd = new Random(); 
     var tbls = new List<Tbl>(); 
     for (int i = 0; i <= 1500; i++) 
     { 
      tbls.Add(new Tbl() 
      { 
       Name = "User" + i + 1, 
       Num = rnd.Next(10, i + 10)/10 
      }); 
      progress.Report(i * 100/1500); 
     } 
     db.Tbls.AddRange(tbls); 
     db.SaveChanges(); 
     return db.Tbls.Count(); 

    }); 
} 

和帶有並行循環:

var task = await Task.Run(() => 
{ 
    int seed = Environment.TickCount; 
    var random = new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed))); 
    var tbls = new ConcurrentBag<Tbl>(); 
    Parallel.For(0, 1500, (i) => { 
     tbls.Add(new Tbl() 
     { 
      Name = "User" + i + 1, 
      Num = random.Value.Next(10, i + 10)/10 
     }); 
    });     
    db.Tbls.AddRange(tbls); 
    db.SaveChanges(); 
    return db.Tbls.Count(); 
}); 

有誰知道是什麼問題?

+2

你的表是否有主鍵?在沒有任何異步和/或並行執行的情況下插入1500條記錄需要多少時間?看一下SQL事件探查器輸出,除了你看到的「insert」命令外,還有什麼「不可見」操作? – Arvo

+0

是的。我的表有主鍵。有或者沒有異步和/或並行執行,大約需要4秒。我也使用代碼第一種方法。 –

+0

這些片段中沒有任何並行數據庫訪問。所有這些片段都完全一樣 - 同步調用SaveChanges。 –

回答

1

如果您想在一次打擊中將大量行加載到數據庫中,那麼您可能會從批量加載中獲得更好的性能。我可以想象,如果加載單個行,則1500個插入操作很容易花費4秒 - 而且由於主要瓶頸是任何數據庫事務所需的最小I/O,您可能無法獲得單個插入顯着更快的運行速度。

對於批量加載API - 例如, SQLBulkCopy - 您準備了一個記錄集,然後在一次打擊中將其加載到數據庫中。這將比1,500個單獨的插入物快得多,快得多。

您尚未指定您需要具有支持批量加載的驅動程序的數據庫平臺。一個SQL Server做的;除非你購買某些版本,否則一些(例如)Oracle版本不會。

+0

我使用sql server。我相信我的代碼至少應該運行少於一秒。但我不知道是什麼原因導致它需要很長時間。 –

+0

您可以請示例在實體框架中嗎? –

+0

OTOH我不知道實體框架是否支持批量加載。您可能需要直接使用SQLBulkCopy API。 – ConcernedOfTunbridgeWells

相關問題