批量更新SQL和VB.net winform

时间:2015-05-05 00:55:28

标签: sql vb.net sql-server-2008

对于SQL Server 2008 +中大型表的批量更新,我将不胜感激,并对其提出了一些想法,讨论和可行性。

目前我有一个包含10,000行和160列的表。此表经常更新,每行有1到100多列更改,具体取决于过程。使用DataAdapter使用“标准新手”表更新非常缓慢且不合适。

任务是寻找更快的方法。我尝试使用批量大小微调DataAdapter.Update,无论更重的更新需要10-15秒。同时SqlBulkCopy导入整个桌子(球场)1-3秒。当更新过程在一个过程中发生30-50次时,10s-15s加起来!

互联网自我思考,我的经验有差距,但我可以想到有两种可能更好地完成更新任务。

  1. 转储数据库中的表格内容,并使用SqlBulkcopy重新填充表格。

  2. 使用带有合并SQL语句传递给它的表的存储过程。

  3. 主要问题是数据安全,虽然这是本地单用户应用程序,但需要有一种方法来处理错误回滚。根据我的理解,转储和替换会更简单,但可能更容易丢失数据?存储过程的设置范围要大得多,因为更新语句必须单独键入所有更新列并保持更改。除非有一个'Update *'声明:)。

    为了保持这种简短,我希望仅将其保持在概念层面,但会欣赏任何不同的想法或链接和建议。

    编辑更多信息: 该表只有一个索引,即ID列。它是将传入(和更改)数据存储到简单数据表的简单过程。并且更新可以是1行到1000行之间的任何位置。程序经常将信息存储到数据库中,并且可以是一些或几乎所有列。为每次更新构建存储过程是不可能的,因为我不知道哪些数据会被更新,你可以说所有列都将被更新(除了ID列和一些“硬”数据列)它依赖于更新输入是什么。因此,除非我每次都列出几乎所有列,否则不会对特定列的更新进行微调。在这种情况下,一个存储过程就可以完成它。

    我认为问题是使用当前数据适配器方法对数据库进行'调用'的次数。

    编辑: 3关于临时表的问题,我将数据批量复制到存储过程然后执行更新。这不会减少SQL流量吗?我认为这是dataadapter更新的问题。

    编辑:在回答此主题时发布了概念1的尝试。

    谢谢

2 个答案:

答案 0 :(得分:0)

删除表并使用批量复制重新加载整个内容不是正确的方法。

我建议为每个更新表的进程创建一个存储过程。该过程应仅将需要为该特定进程更新的列作为输入,然后运行标准SQL更新命令以更新指定行上的那些列。如果可能,尝试在用于查找需要更新的记录的列上建立索引。

或者,根据您使用的.Net框架版本,如果您不想维护整个存储过程列表,可以尝试使用Entity Framework。

答案 1 :(得分:0)

我编写了以下模型来转储表中的所有行,将内存中的表批量复制到sql staging表中,然后将数据移回原始表中。所以通过更新该表中的数据。

时间为1.1至1.3秒

与更新所需的10-15秒相比,肯定是非常有吸引力的时间。我已将登台表的truncete代码放在最上面,以便数据库中始终有一个信息副本。虽然原始表格没有更新的信息,但直到完成该过程。

与这种方法有关的pitfals是什么?我能对他们做些什么?我必须声明该表不可能超过10000行,因此该过程将起作用。

 Try

            ESTP = "Start Bulk DBselection Update"

            Dim oMainQueryT = "Truncate Table DBSelectionsSTAGE"
            Using con As New SqlClient.SqlConnection(RacingConStr)
                Using cmd As New SqlClient.SqlCommand(oMainQueryT, con)
                    con.Open()
                    cmd.ExecuteNonQuery()
                    con.Close()
                End Using
            End Using

            ESTP = "Step 1 Bulk DBselection Update"

            Using bulkCopy As SqlBulkCopy = New SqlBulkCopy(RacingConStr)
                bulkCopy.DestinationTableName = "DBSelectionsSTAGE"
                bulkCopy.WriteToServer(DBSelectionsDS.Tables("DBSelectionsDetails"))
                bulkCopy.Close()
            End Using

            ESTP = "Step 2 Bulk DBselection Update"

            oMainQueryT = "Truncate Table DBSelections"
            Using con As New SqlClient.SqlConnection(RacingConStr)
                Using cmd As New SqlClient.SqlCommand(oMainQueryT, con)
                    con.Open()
                    cmd.ExecuteNonQuery()
                    con.Close()
                End Using
            End Using

            ESTP = "Step 3 Bulk DBselection Update"

            oMainQueryT = "Insert INTO DBSelections Select * FROM DBSelectionsSTAGE"
            Using con As New SqlClient.SqlConnection(RacingConStr)
                Using cmd As New SqlClient.SqlCommand(oMainQueryT, con)
                    con.Open()
                    cmd.ExecuteNonQuery()
                    con.Close()
                End Using
            End Using

            Data_Base.TextBox25.Text = "Deleting data - DONE "
            Data_Base.TextBox25.Refresh()

        Catch ex As Exception

            ErrMess = "ERROR - occured at " & ESTP & " " & ex.ToString
            Call WriteError()
            Call ViewError()

        End Try