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(數據流轉換),即模糊分組和模糊查找。