2012-11-19 110 views
5

在推特上通過#sqlhelp(已解決 - 查看帖子末尾的解決方案)。加速SSIS包裝(插入和更新)

我試圖加快插入2900萬行新數據的SSIS包,然後用2個額外的列更新這些行。到目前爲止,程序包通過包含文件的文件夾循環,將平面文件插入數據庫,然後執行更新並歸檔文件。 添加(感謝@ billinkc):SSIS順序是Foreach循環,數據流,執行SQL任務,文件任務。

什麼不需要很長的時間:循環,文件移動和截斷表(階段)。 什麼需要很長:插入數據,運行低於此聲明:

UPDATE dbo.Stage 
SET Number = REPLACE(Number,',','') 
## Heading ## 
-- Creates temp table for State and Date 
CREATE TABLE #Ref (Path VARCHAR(255)) 
INSERT INTO #Ref VALUES(?) 

-- Variables for insert 
DECLARE @state AS VARCHAR(2) 
DECLARE @date AS VARCHAR(12) 

SET @state = (SELECT SUBSTRING(RIGHT([Path], CHARINDEX('\', REVERSE([Path]))-1),12,2) FROM #Ref) 
SET @date = (SELECT SUBSTRING(RIGHT([Path], CHARINDEX('\', REVERSE([Path]))-1),1,10) FROM #Ref) 

SELECT @state 
SELECT @date 

-- Inserts the values into main table 
INSERT INTO dbo.MainTable (Phone,State,Date) 
SELECT d.Number, @state, @date 
FROM Stage d 

-- Clears the Reference and Stage table 
DROP TABLE #Ref 
TRUNCATE TABLE Stage 

請注意,我已經在插件正在增加每批行和最大插入提交大小玩弄,但也影響了包速度。

解決並補充說:

對於那些有興趣在數字:OP包時間爲11.75分鐘;與威廉的技術(見下文),它下降到9.5分鐘。當然,在2900萬行和較慢的服務器上,這是可以預料的,但希望能夠向您顯示實際數據背後的效果。關鍵是要儘可能多地在數據流任務上發生進程,因爲更新數據(數據流之後)消耗了很多時間。

希望能夠幫助其他人解決類似問題。

更新二:我添加了一條IF語句,並將其從9分鐘縮短爲4分鐘。用於執行SQL任務的最終代碼:

-- Creates temp table for State and Date 
CREATE TABLE #Ref (Path VARCHAR(255)) 
INSERT INTO #Ref VALUES(?) 

DECLARE @state AS VARCHAR(2) 
DECLARE @date AS VARCHAR(12) 
DECLARE @validdate datetime 

SET @state = (SELECT SUBSTRING(RIGHT([Path], CHARINDEX('\', REVERSE([Path]))-1),12,2) FROM #Ref) 
SET @date = (SELECT SUBSTRING(RIGHT([Path], CHARINDEX('\', REVERSE([Path]))-1),1,10) FROM #Ref) 
SET @validdate = DATEADD(DD,-30,getdate()) 

IF @date < @validdate 
BEGIN 
    TRUNCATE TABLE dbo.Stage 
    TRUNCATE TABLE #Ref 
END 
ELSE 
BEGIN 
-- Inserts new values 
INSERT INTO dbo.MainTable (Number,State,Date) 
SELECT d.Number, @state, @date 
FROM Stage d 

-- Clears the Reference and Stage table after the insert 
DROP TABLE #Ref 
TRUNCATE TABLE Stage 
END 
+0

你的包看起來像一個Foreach(文件)循環,消耗所有它找到的文件,並推入一個臨時表中的數據流任務。在完成所有工作之後,您將有一個執行SQL任務將數據從分段移動到實際?緩慢的部分似乎是執行SQL任務?我是否正確理解了這個問題? – billinkc

+0

是的@billinkc。訂單是Foreach循環,數據流,執行SQL任務,文件任務。數據流和執行SQL任務消耗的時間最多(儘管限制數據流可能進行的速度可能存在)。 – Tim

+0

@billinkc它看起來像他的SQL也在他的循環中,因爲他正在將處理文件的路徑傳遞到SQL以檢索日期和狀態。所以看起來Foreach循環包含DataFlow和Execute SQL以及文件系統任務來存檔處理過的文件。 –

回答

5

據我瞭解,你正在閱讀的〜從平面文件2900萬行,寫他們到一個臨時表中,然後運行(讀/寫)的更新SQL腳本相同在暫存表中有29,000,000行,然後將這29,000,000條記錄(從暫存中讀取然後寫入nat)移動到最終表中。

難道你不能從平面文件中讀取數據,使用SSIS轉換來清理數據並添加兩個額外的列,然後直接寫入最終表。那麼你只能對每一組不同的數據進行一次處理,而不是三次處理(6次,如果你計算讀寫次數),那麼你的過程會執行多少次?

我會改變你的數據流轉換過程中所需的項目,並直接寫入我的決賽桌。

編輯

從你的問題看來你是從手機領域移除逗號,然後檢索狀態,並從文件路徑的特定部分的日期轉換數據的SQL是當前然後將這三個數據點存儲在NAT表中。這些事情可以通過數據流中的派生列轉換完成。

對於State和Date列,設置兩個名爲State和Date的新變量。在變量定義中使用表達式將它們設置爲正確的值(就像你在SQL中做的那樣)。當Path變量更新時(在我的循環中,我假設)。狀態和日期變量也會更新。

在派生列轉換中,將狀態變量拖到表達式字段中,並創建一個名爲狀態的新列。

重複日期。

爲手機塔,在派生列transforamtion創建像下面的表達式:

REPLACE([電話], 「」, 「」)

設置派生列字段替換「電話'

對於您的輸出,請創建NAT表的目的地,並將數據流中的Phone,State和Date列鏈接到NAT表中的相應列。

如果您的輸入中有其他列,您可以選擇不從您的來源中引入它們,因爲您似乎只從原始數據中操作電話列。

/編輯

+0

我查看了一些數據轉換,但沒有看到任何允許像我需要的操作的東西。例如,刪除列可以在插入任何東西之前完成,但SSIS中沒有任何工具可以做到這一點。令人驚訝的是,數據操作(在腳本之外)非常有限。 – Tim

+1

令人驚訝的是,我發現我並不需要使用腳本。一般來說,我需要做的任何數據操作都可以通過SSIS中內置的轉換和變量來完成。我需要退回腳本的情況很少。 –

+0

哎呀,看到了編輯 - 我正在檢查變量的想法。 – Tim