Лучшая стратегия для выполнения ETL от постановки до склада
Я создаю консольное приложение C#, которое будет выполняться агентом SQL Server в сценарии, в котором мы хотим передать большой объем данных о сотрудниках:
Между двумя таблицами сотрудников с одинаковой схемой в двух разных сетях от одного экземпляра SQL Server до второго экземпляра SQL Server.
Между двумя таблицами сотрудников в одном экземпляре SQL Server (без задержки в сети), одна таблица является промежуточной таблицей, а другая - хранилищем.
Процесс последовательный, поэтому заданию ETL сначала нужно будет передать номер 1, а затем номер 2.
Мне было интересно, какую стратегию лучше всего использовать для достижения максимальной производительности, учитывая, что процесс № 1 является межсетевым, а процесс № 2 включает удаление таблицы назначения перед передачей в нее новых данных.
Вот что я подумал сделать:
Процесс № 2:
BEGIN TRANSACTION EmployeesInsert
WITH MARK N'Transfering employees from Staging to Warehouse';
GO
USE CorporateWarehouse;
GO
DELETE FROM CorporateWarehouse.WarehouseEmployee
INSERT INTO CorporateWarehouse.WarehouseEmployee
(FirstName,
LastName,
Address,
PhoneNumber)
SELECT FirstName,
LastName,
Address,
PhoneNumber
FROM CorporateWarehouse.StagingEmployee
GO
COMMIT TRANSACTION EmployeesInsert;
GO
1 ответ
Рассмотрев SSIS, BCP и связанные серверы, я, наконец, принял решение реализовать решение с использованием SqlBulkCopy
учебный класс. Начиная со списка пользователей, полученного методом GetUserDataReader(), который возвращает IDataReader
Тип объекта.
Этот вариант был выбран из-за UseInternalTransaction
Опция, вы можете явно заставить его выполнять в своей собственной транзакции:
var usersDataReader = _warehouseRepository.GetUserDataReader();
var connectionString = ConfigurationManager.ConnectionStrings["CorporateWarehouse"].ToString();
using (var bulkCopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction | SqlBulkCopyOptions.TableLock))
{
bulkCopy.BatchSize = extractInfo.BatchSize;
bulkCopy.BulkCopyTimeout = extractInfo.BatchTimeout;
bulkCopy.DestinationTableName = "StagingEmployee";
try
{
bulkCopy.WriteToServer(usersDataReader);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
usersDataReader.Close();
}
}