从登台到仓库执行ETL的最佳策略

时间:2014-07-24 13:20:19

标签: c# sql tsql etl staging-table

我正在构建一个C#控制台应用程序,它将在我们想要传输大量员工数据的情况下由SQL Server代理执行:

  1. 在两个不同网络上具有相同架构的两个员工表之间,从一个SQL Server实例到另一个SQL Server实例。

  2. 在同一SQL Server实例上的两个员工表之间(没有网络延迟),一个表是登台表,另一个表是仓库。

  3. 该过程是顺序的,因此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 个答案:

答案 0 :(得分:2)

在考虑了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();
    }
}