2016-12-07 51 views
4

我加載數據到表中以下列方式:刪除VS回滾策略 - ETL負載

DECLARE @srcRc INT; 
DECLARE @dstRc INT; 

SET @srcRc = (SELECT COUNT(*) FROM A) 

INSERT INTO t 
     (Col1 
     ,Col2 
     ,Col3 
     ) 
     SELECT A.Col1 
       ,A.Col2 
       ,B.Col3 
     FROM A 
       JOIN B 
        ON A.Id = B.Id; 

SET @dstRc = @@ROWCOUNT 

現在我比較變量@srcRc@dstRcROWCOUNT必須相同。如果不是,則需要刪除插入的行。

Q1:回滾插入行的最佳策略是什麼?

我有幾個想法:

1)運行負荷在交易和回滾,如果行數不匹配。
2)標誌列(位)添加到名爲toBeDeleted目標表,運行負荷,如果行數不匹配,與1價值,將其標記爲候選刪除更新toBeDeleted列。然後刪除批處理模式(while-loop)。
或者不要刪除它們,但在使用t表時,始終排除查詢中的刪除候選項。
3)插入行之前,首先比較行數。如果不匹配,請不要啓動負載。

DECLARE @srcRc INT; 
DECLARE @dstRc INT; 
SET @srcRc = (SELECT COUNT(1) FROM A); 
SET @dstRc = (SELECT COUNT(1) FROM A JOIN B ON A.Id = B.Id); 

Q2:什麼是更高金額的行更好的解決方案,讓我們說10-100萬?
問題3:還是有類似的情況下更好的策略?

回答

0

OK,假設:

您需要回滾到一些以後工作時,表A和B的內容可能已經改變

也有可能是你別其他行不想刪除作爲回滾的一部分。

,那麼你必須讓你插入的行的名單,因爲你無法可靠地再生由A和B名單,你不能只在T

刪除一切

您可以通過兩種方式

做到這一點
  • 更改您的導入,以便它首先將行插入到導入表中,使導入表保持四處移動,直到您確定不再需要它爲止。

  • 添加一個額外的列T [importId]您在其中放了唯一標識值

顯然,第一個策略使用了更多的磁盤空間。因此,保存數據的時間越長,數據越多,額外列的外觀就越好。

另一種選擇是單獨生成導入數據的列表,並將您的事務sql作爲批量插入,並將所有數據硬編碼到sql中。

這適用於小列表,初始設置數據等。


編輯:

從您的評論聽起來好像你不想卷每本身回來。但是,在導入過程中應用業務邏輯的最佳方式。

在這種情況下,您的第三個答案是最好的。當您知道源數據不正確時,請勿進行導入。

+0

我只需要回滾「當前」負載,而不是歷史。所以通常我一天一天地加載。今天我加載日期N,明​​天N + 1。所以只檢查當前批次的行數。 如果rowcount不匹配,則所有來自當前加載的內容都需要被擦除,而不僅僅是一些行。 – DNac

+0

這些情況的麻煩在於它不是真正的回滾,除非你撤銷你做的任何事情。任何依賴簡單行數的東西都可能出錯。例如,您複製行x並跳過行y。你的排數將匹配 – Ewan

+0

這是真的,但這種情況從來沒有發生過,我認爲這是非常罕見的。 – DNac