我的任务是开发一种方法,将包含100万或更多行的文本文件导入表格。表中的每一行是856字节,分成大约150“列”的数据。我使用的是SQL Server 2012 Standard Edition。与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进入TEMP TABLE的速度非常快,不到1分钟。但是,我需要解析原始数据并将数据放入其目标表中。为了清楚起见,这意味着,例如,来自行位置1-10的数据应该写入目标表中,11-13应该写入目标表中,等等。我通过使用WHILE循环来执行此操作而不是CURSOR并循环遍历100万行中的每一行,然后将原始数据作为参数传递给另一个存储过程,然后解析原始数据并插入到目标表中。我只是简单地使用SUBSTRING函数解析原始数据,即SUBSTRING(@ rawdata,1,10)。 正如我所提到的,每行中大约有150个字段。然而,解析/写入步骤的性能很糟糕。导入170K行需要10个小时。
目标表上没有聚簇索引。恢复模型设置为SIMPLE。我启用了“即时文件初始化”。
我正在考虑使用SSIS,但是1)我怀疑性能可能不会快得多,2)在SSIS中进行故障排除似乎更麻烦。
寻找我忽略的想法,精彩的想法和明显的建议。
编辑(在WHILE循环中添加了代码):
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
...
)
答案 0 :(得分:4)
不要使用WHILE循环,而是考虑基于集合的解决方案,而不必单独处理每一行。
如果您可以分享更多信息WHILE循环中的代码,我们可能会大大加快速度。即使不使用SSIS; - )
目前我不同意这是“需要”一次解析一行......