Лучшие практики для вставки / обновления большого объема данных в SQL Server 2008

Я строю систему для обновления больших объемов данных через различные каналы CSV. Обычно я просто зацикливаю каждую строку в ленте, выполняю запрос на выборку, чтобы проверить, существует ли элемент, и вставляет / обновляет элемент в зависимости от того, существует он или нет.

Я чувствую, что этот метод не очень масштабируемый и может забить сервер на большие каналы. Мое решение состоит в том, чтобы перебирать элементы как обычно, но сохранять их в памяти. Затем для каждых 100 или около того элементов сделайте выбор из этих 100 элементов и получите список существующих элементов в базе данных, которые соответствуют. Затем объедините операторы вставки / обновления и запустите их в базу данных. Это существенно сократило бы поездки в базу данных.

Является ли это достаточно масштабируемым решением, и есть ли примеры учебных пособий по импорту больших фидов в продуктивную среду?

Спасибо

5 ответов

Решение

Поскольку вы используете SQL Server 2008, я бы порекомендовал этот подход:

  • сначала скопируйте ваши CSV-файлы в промежуточную таблицу
  • обновить целевую таблицу из этой промежуточной таблицы с помощью команды MERGE

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

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

  • строки совпадают, например, строка существует как в исходной, так и в целевой таблице -> обычно вы либо обновляете некоторые поля, либо просто игнорируете их все вместе
  • строка из источника не существует в цели -> как правило, для вставки

Вы бы имели MERGE Заявление примерно так:

MERGE TargetTable AS t
USING SourceTable AS src
ON t.PrimaryKey = src.PrimaryKey

WHEN NOT MATCHED THEN
  INSERT (list OF fields)
  VALUES (list OF values)

WHEN MATCHED THEN
  UPDATE
    SET (list OF SET statements)
;

Конечно, ON пункт может быть гораздо более сложным, если это необходимо. И, конечно же, ваш WHEN утверждения также могут быть более сложными, например,

WHEN MATCHED AND (some other condition) THEN ......

и так далее.

MERGE это очень мощная и очень полезная новая команда в SQL Server 2008 - используйте ее, если можете!

Ваш путь - худшее из возможных решений. В общем, вы не должны думать с точки зрения циклического прохождения записей по отдельности. Раньше у нас был встроенный в компанию инструмент импорта, который просматривал записи, чтобы загрузить файл с более чем миллионом записей, потребовалось бы 18-20 часов (что не часто случалось, когда он создавался, но во много раз наступление дня сейчас).

Я вижу два варианта: во-первых, использовать массовую вставку для загрузки в промежуточную таблицу и выполнить все необходимые операции по очистке этой таблицы. Как вы определяете, существует ли запись? Вы должны быть в состоянии построить обновление на основе набора, присоединившись к промежуточной таблице в тех полях, которые определяют обновление. Часто я добавлял столбец в свою промежуточную таблицу для идентификатора записи, которой он соответствует, и заполнял ее с помощью запроса, а затем выполнял обновление. Затем вы делаете вставку записей, которые не имеют соответствующего идентификатора. Если у вас слишком много записей, чтобы делать все сразу, вы можете запускать партии (что да, это цикл), но делать партии значительно больше, чем 1 запись за раз (я обычно начинаю с 2000, а затем на основе время, которое требуется для этого определения, могу ли я сделать больше или меньше в партии).

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

Альтернатива - использовать SSIS, оптимизированный по скорости. SSIS - сложная вещь, а кривая обучения крутая.

Один из способов - загрузить CSV-файл в DataTable (или, скорее, в DataReader), а затем выполнить пакетный анализ результатов с помощью SqlBulkCopy -

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

Это довольно эффективно, и вы можете сделать некоторые сопоставления столбцов. Совет. При отображении столбцов с помощью SqlBulkCopy они чувствительны к регистру.

Вам нужно кататься здесь вообще? Можно ли предоставить данные таким образом, чтобы SQL Server мог использовать групповой импорт, чтобы загрузить их, а затем обработать дубликаты в базе данных после завершения импорта?

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

Другой подход заключается в написании хранимой процедуры.Net на сервере на сервере для работы со всем файлом...

Только если вам нужно больше контроля, чем у решения Криса Краузе - я большой поклонник того, чтобы сделать его простым (и многократно используемым) там, где мы можем...

Другие вопросы по тегам