Подтвердить что ты не робот

Рекомендации по вставке/обновлению большого объема данных в SQL Server 2008

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

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

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

Спасибо

4b9b3361

Ответ 1

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

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

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

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

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

У вас будет оператор 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 - используйте ее, если сможете!

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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