Vb.net 多线程SQL客户端写入查询
我有一个MS sql数据库(不是服务器),我的程序从2 TB的外部驱动器读取文件结构,并将列表a记录保存在数据库中。我每次写大约8万张唱片,这需要很长时间 我目前正在写记录,把它们分成两个后台工作线程,每个线程40k。我的电脑是四核Phenom II 实现这一点的最佳方法是什么?增加线程数量是否会有任何好处,因为我的硬盘只有7200rpm,而不是raid。我的意思是硬盘可能是一个限制 多谢各位Vb.net 多线程SQL客户端写入查询,vb.net,multithreading,sqlclient,Vb.net,Multithreading,Sqlclient,我有一个MS sql数据库(不是服务器),我的程序从2 TB的外部驱动器读取文件结构,并将列表a记录保存在数据库中。我每次写大约8万张唱片,这需要很长时间 我目前正在写记录,把它们分成两个后台工作线程,每个线程40k。我的电脑是四核Phenom II 实现这一点的最佳方法是什么?增加线程数量是否会有任何好处,因为我的硬盘只有7200rpm,而不是raid。我的意思是硬盘可能是一个限制 多谢各位 编辑:写入所有记录的时间约为15-18分钟。我不使用存储过程。我仅从自动生成的表适配器使用insert
编辑:写入所有记录的时间约为15-18分钟。我不使用存储过程。我仅从自动生成的表适配器使用insert命令。我为每个线程循环insert语句40k次。不,不是基于索引文件进行更新,它们只是插入语句。80k记录不会花费太多时间。你说“非常愉快”,但实际上是什么呢?我们不知道你的相对术语的实际时间 1) 您正在使用存储过程吗? 2) 它是否可以批量处理(BCP或通过在单个命令中生成和发送许多insert/update语句)?
3) 所有更新都使用WHERE子句中的索引字段吗?80k记录不应该花费太多时间。你说“非常愉快”,但实际上是什么呢?我们不知道你的相对术语的实际时间 1) 您正在使用存储过程吗? 2) 它是否可以批量处理(BCP或通过在单个命令中生成和发送许多insert/update语句)?
3) 所有更新都使用WHERE子句中的索引字段吗?我有几点建议: 1) 确保正在写入的数据库和数据库的日志文件都有足够的可用空间来容纳正在写入的数据。动态调整数据库大小对于SQL Server来说是一项非常昂贵的操作,如果您从一个调整百分比很小的小数据库开始,您将不断调整它的大小 2) 在事务中包装insert命令。这将大大提高速度。您可能无法在一个事务中封装所有80k记录,但您可以一次尝试1000条左右。伪代码:
Const MAX_RECORDS_PER_LOOP = 1000
Dim Counter As Integer
Dim trans As SqlTransaction
Try
For Each record In File
' If we are not in a transaction, enter one
If trans Is Nothing Then
trans = conn.BeginTransaction()
End If
' Do your insert
' Boost the counter
Counter += 1
' We have reached the max
If Counter = MAX_RECORDS_PER_LOOP Then
' Commit the previous batch and reset the values
trans.Commit()
trans = Nothing
Counter = 0
End If
Next
' Commit the last batch, if any
If trans IsNot Nothing Then
trans.Commit()
End If
Catch theException As Exception
' Report the exception
' Rollback if trans in progress
If trans IsNot Nothing Then
trans.Rollback()
End If
End Try
我有几个建议: 1) 确保正在写入的数据库和数据库的日志文件都有足够的可用空间来容纳正在写入的数据。动态调整数据库大小对于SQL Server来说是一项非常昂贵的操作,如果您从一个调整百分比很小的小数据库开始,您将不断调整它的大小 2) 在事务中包装insert命令。这将大大提高速度。您可能无法在一个事务中封装所有80k记录,但您可以一次尝试1000条左右。伪代码:
Const MAX_RECORDS_PER_LOOP = 1000
Dim Counter As Integer
Dim trans As SqlTransaction
Try
For Each record In File
' If we are not in a transaction, enter one
If trans Is Nothing Then
trans = conn.BeginTransaction()
End If
' Do your insert
' Boost the counter
Counter += 1
' We have reached the max
If Counter = MAX_RECORDS_PER_LOOP Then
' Commit the previous batch and reset the values
trans.Commit()
trans = Nothing
Counter = 0
End If
Next
' Commit the last batch, if any
If trans IsNot Nothing Then
trans.Commit()
End If
Catch theException As Exception
' Report the exception
' Rollback if trans in progress
If trans IsNot Nothing Then
trans.Rollback()
End If
End Try
你好,Jared Peless,我将信息添加到问题编辑中。感谢您的时间。如果您使用的是表适配器,那么请首先确保您的表已完全填充,然后执行更新/插入操作,这样会提高性能。我只执行插入操作,不使用更新操作,但问题是如何使此过程更快,例如增加线程数,我尝试了最多4个线程,但这比使用2个线程要花更多的时间。在我的测试中,我发现2个线程是最佳点。但是,如果您只是准备好整个表,以便它可以创建一个连接并执行所有插入,那么您可能不需要2个线程。您提到“我正在将insert语句循环40k次”,这似乎表明您正在打开连接、执行语句、关闭连接并继续。如果你能分享一些代码,这可能有助于澄清这一点。你好,贾里德·佩利斯,我在问题编辑中添加了这些信息。感谢您的时间。如果您使用的是表适配器,那么请首先确保您的表已完全填充,然后执行更新/插入操作,这样会提高性能。我只执行插入操作,不使用更新操作,但问题是如何使此过程更快,例如增加线程数,我尝试了最多4个线程,但这比使用2个线程要花更多的时间。在我的测试中,我发现2个线程是最佳点。但是,如果您只是准备好整个表,以便它可以创建一个连接并执行所有插入,那么您可能不需要2个线程。您提到“我正在将insert语句循环40k次”,这似乎表明您正在打开连接、执行语句、关闭连接并继续。如果你能分享一些代码,这可能有助于澄清这一点。