2010-09-08 69 views
7

我正在處理每個50k行的數據塊。 我將它們插入到使用LINQ SQL數據庫:更快的SQL插入?

for(int i=0;i<50000;i++) 
{ 
    DB.TableName.InsertOnSubmit 
    (
     new TableName 
     { 
      Value1 = Array[i,0], 
      Value2 = Array[i,1] 
     } 
    ); 
} 
DB.SubmitChanges(); 

此過程大約需要6分鐘,而我希望它採取可能的話要少得多。有什麼建議麼?

+0

是否有人介紹了大部分時間花費在哪裏? – 2010-09-08 14:52:28

+0

每秒13.88插入看起來非常糟糕的表現!你的數據庫是什麼? – 2010-09-08 14:53:30

+0

我對整個程序做了非常原始的分析,插入佔用了95%的時間。我沒有在插入內部進行分析。 – sooprise 2010-09-08 14:54:00

回答

10

如果您正在閱讀的文件中,您最好使用BULK INSERT (Transact-SQL),如果您一次從內存中寫入多少(50K行),則最好先寫入平面文件,然後再使用批量插入該文件。

+0

我完全同意! – Stefan 2010-09-08 15:07:49

+4

嚴格來說,問題是50K個人插入副本一個批量插入,這是一個任務,你根本不應該考慮使用LINQ來做。這個應該在一組中完成的sisomething。 BULK插件應該在短短不到一分鐘的時間內完成,我曾在16分鐘內在舊的慢速服務器上批量插入2100萬條記錄。 – HLGEM 2010-09-08 15:08:10

+0

數據文件必須在什麼格式?我可以用逗號分隔這些值嗎? – sooprise 2010-09-08 15:29:02

1

由於您正在做一個簡單的插入操作,並且沒有從LinqToSql中獲益太多,請看SqlBulkCopy,它將刪除大部分往返行程並減少Sql Server端的開銷。你將不得不做很少的編碼修改來使用它。

另請參見對錶進行索引的列對數據進行預先排序,因爲這會在SQL-Server更新表時導致更好的緩存命中。

還要考慮如果您應該將數據上傳到未編制索引的臨時登臺表,然後使用單個sql語句將存儲的proc插入到主表中。這可能讓SqlServer分散您的所有CPU的索引工作。

1

有很多事情你需要檢查/做。

  1. 有多少磁盤空間分配給數據庫?有沒有足夠的自由做所有的插入,而不會自動增加大小?如果沒有,增加數據庫文件的大小,因爲它必須停止每一個這麼多插入來自動調整數據庫本身的大小。

  2. 不做個別插入。他們花了太長時間。而是使用表值參數(sql 2008),sql批量複製或單個插入語句(按照優先級順序)。

  3. 之前刪除該表上的任何索引,並在加載後重新創建它們。無論如何,有了這麼多的刀片,它們可能會被分成幾部分。

  4. 如果您有任何觸發器,請考慮刪除它們直到加載完成。

  5. 數據庫服務器中是否有足夠的RAM?你需要檢查服務器本身,看看它是否消耗所有可用的RAM?如果是這樣的話,你可能會考慮在加載之前做一次重啓...... sql server有一種傾向,就是消費並堅持它能夠實現的一切。

  6. 沿着RAM線,我們喜歡在服務器中保留足夠的RAM以將整個數據庫保存在內存中。我不確定這對你是否可行。

  7. 它的磁盤速度如何?隊列深度是否相當長?除了硬件替換之外,這裏沒有太多的事情要做。