SSIS - массовое обновление на уровне поля базы данных - PullRequest
0 голосов
/ 17 марта 2010

Вот наша миссия:

  • Получение файлов от клиентов. Каждый файл содержит от 1 до 1 000 000 записей.
  • Записи загружаются в промежуточную область и применяется проверка бизнес-правил.
  • Действительные записи затем загружаются в базу данных OLTP пакетным способом со следующими правилами:
    • Если запись не существует (у нас есть ключ, поэтому это не проблема), создайте ее.
    • Если запись существует, при необходимости обновите каждое поле базы данных. Решение принимается на основе одного из 3 факторов ... Я не думаю, что важно, что это за факторы.

Наша главная проблема - найти эффективный метод необязательного обновления данных на уровне поля. Это применимо к ~ 12 различным таблицам базы данных, где в каждой таблице может быть от 10 до 150 полей (оригинальный дизайн БД оставляет желать лучшего, но это так и есть).

Наша первая попытка состояла в том, чтобы представить таблицу, которая отражает промежуточную среду (1 поле в подготовке для каждого системного поля) и содержит флаг маскирования. Значение маскирующего флага представляет 3 фактора.

Затем мы поместили ОБНОВЛЕНИЕ, похожее на ...

UPDATE OLTPTable1 SET Field1 = CASE 
  WHEN Mask.Field1 = 0 THEN Staging.Field1
  WHEN Mask.Field1 = 1 THEN COALESCE( Staging.Field1 , OLTPTable1.Field1 )
  WHEN Mask.Field1 = 2 THEN COALESCE( OLTPTable1.Field1 , Staging.Field1 )
...

Как вы можете себе представить, спектакль довольно ужасный.

Кто-нибудь выполнил подобное требование?

Мы - магазин MS, использующий службу Windows для запуска пакетов служб SSIS, которые обрабатывают данные. К сожалению, мы довольно много новичков в этом деле.

Ответы [ 3 ]

0 голосов
/ 22 марта 2010

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

Эта функция крайне важна для создания системы, которая позволяет нескольким участникам использовать процесс, который может иметь самые разные потребности.

Из того, что я прочитал, функция Merge - это скорее отсортированный союз.

0 голосов
/ 22 марта 2010

Мы используем подход, аналогичный тому, который вы описали в нашем продукте для внешних системных входов. (мы обрабатываем пару сотен целевых таблиц, содержащих до 240 столбцов). Как вы описали, существует от 1 до миллиона или более строк.

Как правило, мы не пытаемся настроить одно массовое обновление, мы пытаемся обрабатывать значения одного столбца за раз. Учитывая, что все они представляют собой один тип, представляющий один и тот же элемент данных, промежуточные операторы UPDATE просты. Обычно мы создаем таблицы для сопоставления значений, и это просто

UPDATE target SET target.column = mapping.resultcolumn WHERE target.sourcecolumn = mapping.sourcecolumn.

Настройка отображений немного сложна, но мы снова имеем дело с одним столбцом за раз, делая это.

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

EDIT: Мы также делаем это в пакетах настраиваемого размера, поэтому рабочие наборы и COMMIT никогда не бывают огромными. По умолчанию используется 1000 строк в пакете, но в некоторых конкретных ситуациях было использовано до 40 000 пакетов. Мы также добавляем индексы к рабочим данным для конкретных таблиц.

0 голосов
/ 17 марта 2010

Если вы используете SQL Server 2008, посмотрите на оператор MERGE, здесь это может подойти для ваших потребностей в Upsert.

Можно ли использовать условное разделение для ввода, чтобы отправить строки на другой этап обработки в зависимости от сопоставляемого коэффициента? Похоже, вам может понадобиться сделать это для каждой из 12 таблиц, но потенциально вы можете сделать некоторые из них параллельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...