0

在 ssis 中实现不同操作的最佳选择是哪个?我有一个超过 200 列的表,包含超过 1000 万行。我需要从此表中获取不同的行。使用执行 sql 任务是否明智(使用选择查询来删除行的重复数据)或者是否有任何其他方法可以在 ssis 中实现这一点

我确实知道 ssis 排序组件会删除行的重复数据。但这是一个阻塞组件,使用它根本不是一个好主意...请让我知道您对此的看法

4

3 回答 3

1

我以这种方式分 3 步完成了它:

  1. 将 MillionRow 表转储到 HashDump 表中,该表只有 2 列:Id int identity PK 和 Hash varbinary(20)。该表应在其哈希列上建立索引。
  2. 将 HashDump 表转储到按 Hash 列排序的 HashUni 中。中间是一个脚本组件,它检查当前行的哈希列值是否与前一行相同。如果相同,则将行直接复制到重复输出,否则为唯一。这样,即使您需要的只是唯一的,您也可以记录重复。
  3. 将 MillionRow 表转储到 MillionUni 表中。中间是一个查找组件,它使用 HashUni 来判断哪一行是唯一的。

此方法允许我使用以下消息记录每个重复项:“第 1000 行是第 100 行的副本”。

我还没有找到比这更好的方法。早些时候,我在 MillionUni 上做了一个唯一索引,将 MillionRow 直接转储到其中,但我无法使用“快速加载”,这太慢了。

这是填充 Hash 列的一种方法:

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    StringBuilder sb = new StringBuilder();
    sb.Append(Row.Col1String_IsNull ? "" : Row.Col1String); sb.Append("|");
    sb.Append(Row.Col2Num_IsNull ? "" : Row.Col2Num.ToString()); sb.Append("|");
    sb.Append(Row.Col3Date_IsNull ? "" : Row.Col3Date.ToString("yyyy-MM-dd"));
    var sha1Provider = HashAlgorithm.Create("SHA1"); 
    Row.Hash = sha1Provider.ComputeHash(Encoding.UTF8.GetBytes(sb.ToString()));
}

如果 200 列对您来说是件苦差事,那么本文的一部分内容将激发您的灵感。它正在将所有列对象的值循环到一个字符串中。

要比较哈希,请使用以下方法

byte[] previousHash;
int previousRowNo;

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    if (StructuralComparisons.StructuralEqualityComparer.Equals(Row.Hash, previousHash))
    {
        Row.DupRowNo = previousRowNo;
        Row.DirectRowToDuplicate();
    }
    else
    {
        Row.DirectRowToUnique();
    }
    previousHash = Row.Hash;
    previousRowNo = Row.RowNo;
}
于 2015-08-18T11:31:24.730 回答
0

我不会为它打扰 SSIS,几个查询就可以了;你还有很多数据,所以我建议你在运行查询之前检查执行计划,并优化你的索引

http://www.brijrajsingh.com/2011/03/delete-duplicate-record-but-keep.html

查看我在同一主题上写的一篇小文章

于 2013-08-16T13:02:57.150 回答
0

据我所知,排序组件是唯一可以让您区分两面性的转换。或者你可以使用类似 SQL 的命令。
如果排序操作有问题,那么您应该在数据访问模式规范中使用(假设您的源是 DB)“SQL 命令”。选择不同的数据,就是这样。您还可以节省一点时间,因为 ETL 不必通过排序组件。

在此处输入图像描述

于 2013-08-16T13:25:18.190 回答