5

我首先要说的是,能够从平面文件中获取1700万条记录,推送到远程盒上的数据库并使其花费7分钟,这是惊人的。 SSIS真的太棒了。但是现在我有那些数据了,如何删除重复项?如何使用SSIS从平面文件中删除重复的行?

更好的是,我想采取平面文件,从平面文件中删除重复项,并将它们放回到另一个平面文件。

我想到一个:包含一些逻辑来

Data Flow Task

  • 文件源(与关联的文件连接)
  • for循环容器
  • 脚本容器告诉是否存在另一行

谢谢你,这个网站上的每个人都非常有知识。

Update:I have found this link, might help in answering this question

+0

当你说“重复”时,你是指记录是相同的,还是记录主键相同的记录? – 2008-09-30 09:47:19

回答

5

我建议使用SSIS的记录复制到一个临时表,然后创建一个使用SELECT DISTINCT或等级根据您的情况任务选择这将它们漏斗方式的重复平面文件并从临时表中删除它们。最后一步是将记录从临时表复制到目标表中。

确定重复是SQL擅长的,但平面文件不太适合。在你提出的情况下,脚本容器将加载一行,然后将其与1700万条记录进行比较,然后加载下一行并重复......性能可能不是那么好。

+0

而且速度更快。 – thotwielder 2013-03-04 12:50:03

1

该策略通常取决于临时表有多少列。列越多,解决方案就越复杂。你链接的文章有一些非常好的建议。

我将添加到其他人迄今为止所说的唯一的事情是,具有日期和日期时间值的列将给出一些适合的解决方案。我想出了

一种解决方案是这样的:

SET NOCOUNT ON 

DECLARE @email varchar(100) 

SET @email = '' 

SET @emailid = (SELECT min(email) from StagingTable WITH (NOLOCK) WHERE email > @email) 

WHILE @emailid IS NOT NULL 
BEGIN 

    -- Do INSERT statement based on the email 
    INSERT StagingTable2 (Email) 
    FROM StagingTable WITH (NOLOCK) 
    WHERE email = @email 

    SET @emailid = (SELECT min(email) from StagingTable WITH (NOLOCK) WHERE email > @email) 

END 

这是在做重复数据删除的时候快了很多,比游标,不会挂在服务器的CPU。要使用它,请将每个来自文本文件的列分隔到自己的变量中。在循环之前和之内使用单独的SELECT语句,然后将它们包含在INSERT语句中。这对我来说真的很好。

+0

Hector,当谈到这个SSIS努力时,你将成为我的救星!非常感谢! – RyanKeeter 2008-09-29 23:10:26

+0

一个很高兴成为服务。 ;) – 2008-09-29 23:49:01

1

要做到这一点的平面文件,我使用Unix命令行工具,排序:

sort -u inputfile > outputfile 

不幸的是,窗户sort命令没有一个独特的选项,但你可以尝试下载一个排序实用程序从下列操作之一:

(我没有尝试过,所以没有保证,恐怕)。另一方面,为了将这些记录加载到数据库中,您可以在数据库表的关键字ignore_dup_key上创建一个唯一索引。这会使记录在加载时非常高效。

CREATE UNIQUE INDEX idx1 ON TABLE (col1, col2, ...) WITH IGNORE_DUP_KEY 
1

有点肮脏的解决方案是用横跨所有列的组合键设置您的目标表。这将保证失真的独特性。然后在数据目的地形状中,将任务配置为忽略错误。所有重复插入将被遗忘。

20

使用排序组件。

只需选择您希望在左下角排列加载行的区域,您将看到一个复选框以删除重复项。此框移除它们是基于排序标准只有这么在行下面的例子 副本将被认为是重复的,如果我们只排序的第一个字段的任何行:

1 | sample A | 
1 | sample B | 
3

平面文件源 - >汇总(按专栏分组) - >平面文件目标

0

我建议在目标服务器上加载临时表,然后将结果合并到目标服务器上的目标表中。如果您需要运行任何卫生规则,那么您可以通过存储过程执行此操作,因为您必须获得比通过SSIS数据流转换任务更好的性能。此外,重复数据删除通常是一个多步骤的过程。您可能想要重复数据删除:

  1. 不同的行。
  2. 独特的列组,如名字,姓氏,电子邮件地址等
  3. 您可能希望对现有目标表进行重复数据删除。如果是这样的话,那么你可能需要包含NOT EXISTS或NOT IN语句。或者您可能想要使用新值更新原始行。这通常最好用MERGE语句和源代码的子查询。
  4. 采取特定模式的第一行或最后一行。例如,您可能需要为文件中输入的每个电子邮件地址或电话号码输入最后一行。我通常依靠具有ROW_NUMBER()的CTE来生成连续订单和反向订单列,如下面的示例所示:

WITH  
    sample_records 
    (  email_address 
     , entry_date 
     , row_identifier 
    ) 
    AS 
    (
      SELECT  '[email protected]' 
        , '2009-10-08 10:00:00' 
        , 1 
     UNION ALL 

      SELECT  '[email protected]' 
        , '2009-10-08 10:00:01' 
        , 2 

     UNION ALL 

      SELECT  '[email protected]' 
        , '2009-10-08 10:00:02' 
        , 3 

     UNION ALL 

      SELECT  '[email protected]' 
        , '2009-10-08 10:00:00' 
        , 4 

     UNION ALL 

      SELECT  '[email protected]' 
        , '2009-10-08 10:00:00' 
        , 5 
    ) 
, filter_records 
    (  email_address 
     , entry_date 
     , row_identifier 
     , sequential_order 
     , reverse_order 
    ) 
    AS 
    (
     SELECT email_address 
      , entry_date 
      , row_identifier 
      , 'sequential_order' = ROW_NUMBER() OVER (
             PARTITION BY email_address 
             ORDER BY  row_identifier ASC) 
      , 'reverse_order'  = ROW_NUMBER() OVER (
             PARTITION BY email_address 
             ORDER BY  row_identifier DESC) 
     FROM sample_records 
    ) 
    SELECT  email_address 
      , entry_date 
      , row_identifier 
    FROM  filter_records 
    WHERE  reverse_order = 1 
    ORDER BY email_address; 

有很多关于重复数据删除的文件为你的选择,但最终我建议在存储过程中,一旦你已经装载在目标服务器上一个临时表处理这个。清理数据后,您可以将MERGE或INSERT到最终目的地。

0

找到了这个网页link text可能是值得考虑的,虽然17万条记录可能需要一段时间太长

1

我们可以利用查找表这一点。就像SSIS提供了两个DFS(数据流转换),即模糊分组和模糊查找。