0

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

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

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

谢谢你。

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

4

2 回答 2

2

80k 条记录不应该花费大量时间。您说“美好时光”,但实际上是什么?我们不知道您的相对任期的实际时间。

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

于 2011-12-14T11:50:12.230 回答
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
于 2011-12-14T18:15:55.653 回答