2008-12-02 133 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

感谢所有的帮助!我衷心感谢。