SSIS仅添加更改的行

时间:2015-11-20 14:56:19

标签: c# sql-server datatable ssis

我有一个项目,包括将所有用户(包括其所有属性)从Active Directory域导入SQL Server表。此表将由Reporting Services应用程序使用。

enter image description here

表模型包含以下列:  -ID :(自动生成的唯一标识符)。  -distinguishedName:包含用户的LDAP专有名称属性。  -attribute_name:包含用户属性的名称。  -attribute_value:包含属性值。  -timestamp:包含自动生成的日期时间值。

我创建了一个带有脚本任务的SSIS包,其中包含一个C#代码,该代码将所有数据导出到稍后由数据流任务导入到表中的.CSV。该项目没有任何问题,但生成了超过2百万行(AD域有大约30.000个用户,每个用户有100-200个属性)。

SSIS包应该每天运行,并且只有在新的用户属性或属性值发生变化时才导入数据。

为了做到这一点,我创建了一个数据流,将整个表复制到一个记录集中。

enter image description here

enter image description here

此记录集将转换为数据表,并在脚本组件步骤中使用,该步骤将验证数据表中是否存在当前行。如果该行存在,则比较属性值并仅在值不同或在数据表中找不到行时才将行返回到输出。这是代码:

  

块引用

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    bool processRow = compareValues(Row);

    if (processRow)
    {
        //Direct to output 0
        Row.OutdistinguishedName = Row.distinguishedName.ToString();
        Row.Outattributename = Row.AttributeName.ToString();
        Row.Outattributevalue.AddBlobData(System.Text.Encoding.UTF8.GetBytes(Row.AttributeValue.ToString()));
    }
}

public bool compareValues(Input0Buffer Row)
{
    //Variable declaration
    DataTable dtHostsTbl = (DataTable)Variables.dataTableTbl;
    string expression = "", distinguishedName = Row.distinguishedName.ToString(), attribute_name = Row.AttributeName.ToString(), attribute_value = Row.AttributeValue.ToString();
    DataRow[] foundRowsHost = null;

    //Query datatable
    expression = "distinguishedName LIKE '" + distinguishedName + "' AND attribute_name LIKE '" + attribute_name + "'";
    foundRowsHost = dtHostsTbl.Select(expression);

    //Process found row
    if (foundRowsHost.Length > 0)
    {
        //Get the host id
        if (!foundRowsHost[0][2].ToString().Equals(attribute_value))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return true;
    }
}

代码正常运行,但速度非常慢。有没有更好的方法呢?

1 个答案:

答案 0 :(得分:0)

以下是一些想法:

选项A. (实际上是选项的组合)

  1. 使用whenChanged属性查询Active Directory时消除不必要的数据。 仅这一点就可以显着减少记录数量。 如果无法按whenChanged进行过滤,或者除此之外,请考虑以下步骤。

  2. 而不是将所有现有记录导入Recordset Destination - 将其导入Cache Transform。 然后在2 Lookup个组件的缓存连接管理器中使用此缓存转换。 One Lookup组件验证{distinguishedName,attribute_name}组合是否存在。 (这将插入然后) 另一个查找组件验证{distinguishedName,attribute_name,attribute_value}组合是否存在。(这将是更新,或删除/插入)。 这对查找应该替换您的Skip rows which are in the table脚本组件。

  3. 评估是否可以减少列大小:attribute_nameattribute_value。特别是nvarchar(max)经常破坏党。

  4. 如果无法缩小attribute_nameattribute_value的大小 - 请考虑存储其哈希并验证哈希值是否已更改,而不是验证值本身。

  5. 删除CSV步骤 - 只需将数据从当前填充CSV的初始源传输到一个数据流中的查找,以及查找中找不到的任何内容 - 发送到OLE DB Destination组件。

  6. 选项B。

    检查从Active Directory读取的源是否很快。 (只需单独使用该源运行数据流,无需任何目标来衡量其性能)。 如果您对其性能感到满意,并且如果您没有反对删除ad_User表中的所有内容 - 只需删除并重新填充每天200万个。 在同一数据流中读取AD中的所有内容并写入SQL Server,无需任何更改检测,实际上可能是最简单,最快速的选项。