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

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

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

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

спасибо

5 ответов


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

  • сначала bulkcopy ваши 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-используйте ее, если сможете!


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

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

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


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

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

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

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


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

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


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

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