C # и SQL Server 2008 - пакетное обновление - PullRequest
1 голос
/ 01 декабря 2011

У меня есть требование, когда мне нужно обновить тысячи записей в таблице активной базы данных, и хотя в этой таблице много столбцов, мне нужно обновить только 2-3 столбца.

Кроме того, я не могу обратиться к базе данных тысячу раз просто для обновления, которое можно выполнить в пакетном обновлении с использованием параметра SQL Server Table Valued Parameter. Но опять же, я не должен обновлять все тысячи записей за один раз для лучшей обработки ошибок, вместо этого я хочу обновлять записи в пакетах по x * 100.

Итак, мой подход ниже, пожалуйста, дайте ваши ценные данные для любых других альтернатив или любых изменений в предлагаемом процессе -

  • 1 Извлечение необходимых записей из базы данных в List<T> MainCollection
  • 2 Сохранить эту коллекцию в файл XML с каждым элементом Status = Pending
  • 3 Возьмите первые 'n' элементы из файла XML с помощью Status = Pending и добавьте их в новый List<T> SubsetCollection
  • 4 Loop over List<T> SubsetCollection - внести необходимые изменения в T
  • 5 Преобразовать List<T> SubsetCollection в таблицу данных
  • 6 Процедура обновления вызова сохранена и передана в DataTable как TVP
  • 7 Обновление Status = Processed для XML-элементов, соответствующих List<T> SubsetCollection
  • 8 Если в файле XML существует больше записей со статусом «Ожидание», перейдите к шагу № 3.

Пожалуйста, руководство для лучшего подхода или улучшения в вышеуказанном процессе.

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

Я бы применил подход, основанный только на базе данных, если это возможно, и, если не возможно, исключу части, которые будут самыми медленными. Если вы не можете выполнить всю работу в хранимой процедуре, извлеките все записи и внесите изменения.

Следующим шагом является запись изменений в промежуточную таблицу с помощью SQL Bulk Copy. Это быстрая массовая загрузка, которая скопирует тысячи записей в считанные секунды. Вы будете хранить первичный ключ и столбцы для обновления, а также номер партии. Номер партии присваивается каждой партии записей, что позволяет загружать другую партию, не конфликтуя с первой партией.

Используйте хранимую процедуру на сервере для обработки записей партиями по 100 или 1000 в зависимости от производительности. Передайте номер партии в хранимую процедуру.

Мы используем такой метод для загрузки и обновления миллионов записей в пакетном режиме. Наилучшая скорость достигается за счет исключения сети и разрешения серверу базы данных выполнять большую часть работы.

Я надеюсь, что это может дать вам альтернативное решение для оценки.

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

Возможно, это не лучшая практика, но вы могли бы встроить некоторую логику в функцию CLR SQL Server.Эта функция может быть вызвана Query, StoProc или расписанием для запуска в определенное время.

Единственная проблема, которую я вижу, - получение шага 4 для внесения необходимых изменений в T.Внедрение этой логики в базу данных может отрицательно сказаться на обслуживании, но это ничем не отличается от людей, которые встраивают огромные объемы бизнес-логики в StoProcs.

В любом случае функции SQLR CLR могут быть подходящим способом.Вы можете создать их в Visual Studio 2008, 2010 (Проверьте базу данных новых типов проектов).

Учебник: http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.80).aspx

...