我的任務是開發一種將具有100萬或更多行的文本文件導入到表中的方法。表格中的每行都是856字節,分成大約150個「列」數據。我正在使用SQL Server 2012標準版。與INSERT相關的活動是數據庫上的唯一活動。我建立了一個存儲過程執行以下操作:超過100萬行的SQL Server BULK INSERT - 需要性能改進
GET LIST OF UNIMPORTED DATA FILES IN A SPECIFIC DIRECTORY
LOOP THROUGH LIST OF FILES
BULK INSERT INDIVIDUAL FILE DATA INTO (DISK-BASED) TEMP TABLE
LOOP THROUGH RECORD-LEVEL DATA IN TEMP TABLE
PARSE/WRITE RECORD-LEVEL DATA TO DETAILRECORD TABLE
IF ALL RECORDS FOR A GIVEN FILE ARE SUCCESSFULLY WRITTEN TO THE DETAIL RECORD TABLE
THEN
MOVE FILE TO IMPORTED_FILES DIRECTORY
WRITE SUCESS RECORD TO IMPORTLOG TABLE
ELSE
WRITE FAIL RECORD TO IMPORTLOG TABLE
MOVE ON TO NEXT FILE
原始文本文件到臨時表的BULK INSERT是速度不夠快,在不到1分鐘。但是,我需要分析原始數據並將數據放入目標表中。清楚地說,這意味着,例如,應將來自行位置1-10的數據寫入目標表中,將11-13寫入目標表中,等等。我通過使用WHILE循環而不是CURSOR並遍歷100萬行中的每一行,然後將原始數據作爲參數傳遞給另一個存儲過程,然後解析原始數據並插入到目標表中。我只是通過使用SUBSTRING函數,即SUBSTRING(@ rawdata,1,10)來解析原始數據。正如我所提到的,每行中大約有150個字段。但是,解析/寫入步驟的性能很糟糕。進口170K行花費了10個小時。
目標表上沒有聚集索引。恢復模式設置爲SIMPLE。我已啓用「即時文件初始化」。
我在尋找可能使用SSIS,但1)我懷疑性能可能不會更快,並且2)SSIS中疑難解答似乎更麻煩。
尋找想法,出色的想法和我忽略的明顯建議。
WHILE @RecordCounter <= @FileRecordCount
BEGIN
SELECT @Record = record FROM CDR.tempFile WHERE id = @RecordCounter
EXEC [CDR].[usp_ImportCDRData_Record] @pRecord = @Record, @pCarrier = @carrier, @pLogid = @ImportLogID
SET @RecordCounter = @RecordCounter + 1
END
--Inside [CDR].[usp_ImportCDRData_Record]
INSERT INTO dbo.DetailRecord
(
LOGID ,
ACCOUNTNUMBER ,
CORPID ,
SERVICELOCATION ,
NETWORKINDICATOR ,
...
)
VALUES
(
@pLogID,
SUBSTRING(@pRecord, 1,10), -- ACCOUNTNUMBER
SUBSTRING(@pRecord, 11,8), -- CORPID
SUBSTRING(@pRecord, 19,8), -- SERVICELOCATION
SUBSTRING(@pRecord, 27,1), -- NETWORKINDICATOR
...
)
這似乎是一個非常適合的ETL工具,而不是試圖完全在T-SQL中完成。我沒有使用過SSIS,但是在Talend中這將是相當微不足道的。 – ydaetskcoR 2014-09-13 13:56:26
CLR是解決複雜分裂的一種可能的解決方案。你是否有理由在循環中完成任務? – u07ch 2014-09-13 14:09:03
投票移動到http://dba.stackexchange.com/ – Mihai 2014-09-13 14:13:51