多线程SQL客户端编写查询

时间:2011-12-14 11:43:39

标签: vb.net multithreading sqlclient

我有一个MS sql数据库(不是服务器),我的程序从我的2 TB外部驱动器读取文件结构并将列表保存在数据库中。我每次写大约8万条记录,这需要很长时间。

我目前正在编写记录,将它们分成2个后台工作线程,每个40k。我的电脑是四核Phenom II。

实现这一目标的最佳方法是什么?通过增加线程数量也会有任何好处,因为我的硬盘只有7200rpm,而不是raid。我的意思是HDD可能是一个限制?

谢谢。

编辑:时间写入所有记录大约15-18分钟。我没有使用存储过程。我只使用自动生成的表适配器中的insert命令。我为每个线程循环插入语句40k次。不,不基于索引文件进行更新,它们只是插入语句。

2 个答案:

答案 0 :(得分:2)

80k记录不应该占用大量时间。你说“美好的时光”,但实际上是什么?我们不知道你的相对术语的实际时间。

1)您使用的是存储过程吗? 2)是否可以批量处理(BCP或在单个命令中生成和发送许多插入/更新语句)? 3)是否所有更新都使用WHERE子句中的索引字段?

答案 1 :(得分:1)

我有几点建议:

1)确保要写入的数据库的数据库和日志文件都有足够的可用空间来容纳您正在编写的数据。动态调整数据库大小对于SQL Server来说是一项非常昂贵的操作,如果您从一个调整大小很小的小型数据库开始,您将不断调整它的大小。

2)在事务中包装插入命令。这应该大大提高速度。您可能无法在单个事务中包装所有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