Многопоточность SQL Client Write запросы - PullRequest
0 голосов
/ 14 декабря 2011

У меня есть база данных MS SQL (не сервер), моя программа считывает файловую структуру с моего внешнего диска объемом 2 ТБ и сохраняет список записей в базе данных.Я пишу около 80 тыс. Записей каждый раз, и это занимает много времени.

В настоящее время я пишу записи, разделив их на 2 фоновых рабочих потока по 40 КБ каждая.Мой компьютер - четырехъядерный Phenom II.

Каков наилучший способ достичь этого, а также были бы какие-то преимущества за счет увеличения числа потоков, потому что у меня всего 7200 об / мин, а не рейд.Что я имею в виду, что жесткий диск может быть ограничением?

Спасибо.

Редактировать: Время записи всех записей составляет около 15-18 минут. Я не использую сохраненныепроцедуры.Я использую команду вставки только из автоматически сгенерированных табличных адаптеров.Я зацикливаю оператор вставки 40k раз для каждого потока.Нет, обновление не выполняется на основе индексированного файла, это просто оператор вставки.

Ответы [ 2 ]

2 голосов
/ 14 декабря 2011

80 тыс. Записей не должны занимать много времени.Вы говорите "прекрасное время", но что это на самом деле?Мы не имеем представления о фактическом времени вашего относительного термина.

1) вы используете хранимые процедуры?2) Это что-то, что может быть обработано навалом (BCP или с множеством операторов вставки / обновления, созданных и отправленных в одной команде)?3) Все ли обновления используют индексированные поля в предложении WHERE?

1 голос
/ 14 декабря 2011

У меня есть пара предложений:

1) Убедитесь, что и база данных, и файл журнала базы данных, которую вы пишете, имеют более чем достаточно свободного места для размещения данных, которые вы пишете. Динамическое изменение размера баз данных является очень дорогой операцией для SQL Server, и если вы начнете с небольшой базы данных с небольшим процентом изменения размера, вы будете постоянно изменять ее.

2) Оберните ваши команды вставки в транзакцию. Это должно существенно улучшить скорость. Вероятно, вы не сможете обернуть все 80 тыс. Записей в одну транзакцию, но вы можете попробовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...