2008-12-02 136 views
15

我試圖從Vb.Net插入大量的記錄到SQL Server 2005中。雖然插入工作正常,但我盡我所能努力盡快完成。目前,100,000條記錄需要大約11分鐘。從應用程序中將大量記錄插入SQL Server的建議方法是什麼?大量插入到SQL服務器

我目前的apporach基本上是打開連接,遍歷我的信息列表並觸發單個sql插入語句,然後關閉連接。任何人有更好的建議如何做到這一點?

當前功能:

Public Sub BatchInsert(ByVal ParamCollections As List(Of SqlParameter())) 

    Dim Conn As SqlConnection = New SqlConnection(DBHelper.DatabaseConnection) 
    Using scope As TransactionScope = New TransactionScope() 
    Using Conn 

     Dim cmd As SqlCommand = New SqlCommand("sproc_name", Conn) 

     Conn.Open() 
     cmd.CommandType = CommandType.StoredProcedure 

     For i = 0 To ParamCollections.Count - 1 

      cmd.Parameters.Clear() 
      cmd.Parameters.AddRange(ParamCollections(i)) 
      cmd.ExecuteNonQuery() 

     Next 

     Conn.Close() 
     scope.Complete() 
    End Using 
    End Using 

End Sub 

回答

19

使用SqlBulkCopy類,它能夠通過這些100K行不是單個刀片更快的運行。

哦,如果可以的話,我會敦促你實現一個IDataReader的能力級別,爲SqlBulkCopy.WriteToServer(IDataReader)提供方法,這將允許你按順序產生一行數據。作爲一個例子,如果您從文本文件導入,則構建一些使用yield return並將其轉換爲IDataReader對象的方法IEnumerable<T>將允許您非常自然地向服務器提供數據。

爲了防止BCP的回滾能力的丟失,您可以將數據傳輸到臨時表中,然後在服務器上執行正常的INSERT INTO語句,然後將數據從臨時表批量傳輸到生產表中,將允許您爲最後一個轉賬部分使用交易,並且運行速度仍將比原始單個插入報表快得多。

編輯:和Here's an example(C#,但應該很容易轉換爲VB.Net)大容量加載API的使用。

+0

只要OP沒有記錄這些交易即可,這很好。使用BCP將消除回滾數據的能力(不像其大部分時間真正使用的那樣)。 – StingyJack 2008-12-02 18:28:08

0

這取決於如何實現批量複製類。但是有一個命令行工具包含在SQL Server的安裝中,它完全可以做到這一點(它可能是相同的)。它被稱爲「bcp」。我現在正在使用它,它應該能夠在幾秒鐘內通過10萬行的風暴。

MSDN文檔將其稱爲「批量導入」實用程序。

1

還有一個存儲過程(稱爲大容量插入),將爲你做的伎倆..它使用封底下的bcp。

退房此鏈接查看語法

link text

2

把你的數據導入到一個CSV文件,並運行在數據bcp實用工具。順序調用一次只能插入一行,你無法獲得更快的速度,如果你需要性能,你肯定需要一個批量工具。

SQLBulkCopy類將允許您傳輸集合中的所有數據,以便服務器可以一次處理所有內容,消除來回。所以,如果你想避免創建臨時文件(我會),然後看看那個類。

只要連接保持打開狀態是一個好的開始,但是您仍然有發送行,SQL存儲它返回結果的開銷,然後您必須迭代到下一行。

11

感謝大家的幫助,我完成了我的任務。 SQLBulkCopy完全符合我的需求(雖然還有其他一些很好的建議)。使用SqlBulkcopy,時間從11分鐘到45秒。我簡直不敢相信!

以供將來參考,這裏是信息的幾個位:

  • 要使用SQL批量複製,您的數據必須是在DataSet,DataReader的,或數據表的形式。一些XML也是允許的。

基本實現代碼:

Public Sub PerformBulkCopy(ByVal dt As DataTable) 

    Using Conn As SqlConnection = New SqlConnection(DBHelper.DatabaseConnection) 
     Conn.Open() 

     Using s As SqlBulkCopy = New SqlBulkCopy(Conn) 

      s.DestinationTableName = "TableName" 
      s.WriteToServer(dt) 
      s.Close() 

     End Using 

     Conn.Close() 
    End Using 
End Sub 

非常豐富的鏈接,我發現:

Using Sql Bulk Copy

感謝所有的幫助!我衷心感謝。