Использование SqlBulkCopy для фиксации данных для учебной / демонстрационной среды - проблемы производительности и способы загрузки - PullRequest
0 голосов
/ 23 октября 2019

Я перемещаю данные из одного набора исходных баз данных Sql Server в другой набор целевых баз данных SQL Server. Первоначальным подтверждением концепции было копирование данных как есть. Следующим шагом была обработка каждой записи для «фиксации» данных, отмеченных в файле конфигурации (например, Имя, Фамилия, Адрес, SSN и т. Д.).

Виртуальная машина Windows, на которой я работаю, имеет 4 ГБПамять. Я вижу очень длительное время выполнения, просто пытаюсь скопировать данные из таблицы исходной базы данных в ее таблицу назначения. У меня есть несколько таблиц, которые превышают 100 миллионов записей, но большинство таблиц меньше миллиона. Похоже, что мой процесс сталкивается с множеством серьезных сбоев и использует всю доступную память.

Я мог бы использовать SqlDataReader, но мне нужно обновить данные в каждой строке перед записью в целевую базу данных. Поэтому я использую DataTable, который явно читает все записи в память. Но я не уверен, что правильный способ обработки записей в пакетном режиме (чтение первых 1000, фиксация данных, запись в место назначения, затем чтение следующих 1000 записей и т. Д.)? Есть ли детерминированный способ чтения записей из таблицы через C #? После долгих поисков я не смог найти ничего определенного.

Код:

DataTable dataTable = new DataTable();

SqlCommand cmd = new SqlCommand("SELECT * FROM " + tableName, srcConn);

using (SqlDataAdapter da = new SqlDataAdapter(cmd))

{

    da.Fill(dataTable);

    da.Dispose();

}

CopyAndFictionalizeTable(tableName, fields, dataTable);

var transaction = destConn.BeginTransaction();
var options = SqlBulkCopyOptions.KeepNulls | SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.TableLock;
using (SqlBulkCopy bulkData = new SqlBulkCopy(destConn, options, transaction))
{

    bulkData.BatchSize = 5000;
    bulkData.BulkCopyTimeout = 0;
    bulkData.DestinationTableName = tableName;
    bulkData.WriteToServer(dataTable);
}
transaction.Commit();
...