批量插入Sql Server

时间:2008-12-02 18:17:24

标签: sql-server vb.net performance

我试图从Vb.Net向SQL Server 2005插入大量记录。虽然插入工作正常,但我正尽力尽力使其尽快完成。目前,100,000条记录需要大约11分钟。从应用程序中将大量记录插入SQL Server的建议方法是什么?

我当前的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

6 个答案:

答案 0 :(得分:20)

使用SqlBulkCopy类,它可以比单个插入快得多地运行这些100K行。

哦,如果可以的话,我会敦促你实现一个IDataReader能力的类来提供SqlBulkCopy.WriteToServer(IDataReader)方法,这将允许你按顺序生成数据,一次一行。如果您要从文本文件导入,作为示例,构建一些使用IEnumerable<T>并将其转换为IDataReader对象的yield return方法将允许您非常自然地将数据提供给服务器

为了解决BCP丢失回滚能力的问题,您可以将数据传输到临时表中,然后在服务器上执行正常的INSERT INTO语句,将数据从临时表批量传输到生产中table,这将允许您使用最后一个传输部分的事务,并且仍然比原始的单个插入语句运行得快得多。

编辑:和Here's an example(C#,但应该很容易转换为VB.Net)批量加载API的使用。

答案 1 :(得分:11)

感谢大家的帮助,我完成了我的任务。 SQLBulkCopy完全符合我的需求(尽管还有其他一些很好的建议)。使用SqlBulkcopy,时间从11分钟到45秒。我简直不敢相信!

供将来参考,以下是一些信息:

  • 要使用SQL批量复制,您的数据必须采用DataSet,DataReader或DataTable的形式。也允许一些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

感谢大家的帮助!我真诚地感激它。

答案 2 :(得分:2)

将您的数据导入csv文件并对数据运行bcp实用程序。对于一次插入单行的顺序调用,您无法获得更快的速度,如果您想要性能,则肯定需要批量实用程序。

SQLBulkCopy类允许您传输集合中的所有数据,以便服务器可以一次处理所有内容,从而消除来回。因此,如果您想避免创建临时文件(我会这样做),那么请查看该类。

只是让连接保持打开是一个好的开始,但你仍然有发送行的开销,让SQL存储它,返回结果,然后你必须迭代到下一行。

答案 3 :(得分:2)

以下是将文本文件导入sql server的不同方法的速度比较: http://weblogs.sqlteam.com/mladenp/archive/2006/07/22/10742.aspx

希望它有所帮助。

答案 4 :(得分:1)

还有一个存储过程(称为Bulk Insert)可以帮助你。它使用了bcp。

查看此链接以查看语法

link text

答案 5 :(得分:0)

这取决于批量复制类的实现方式。但是有一个命令行工具包含安装的SQL Server,它正是这样做的(它可能是相同的)。它被称为“bcp”。我现在正在使用它,应该能够在几秒钟内完成10万行。

MSDN文档将其称为“批量导入”实用程序。