加速SSIS包(插入和更新)

时间:2012-11-19 21:36:45

标签: sql-server ssis performance

在Twitter上由#sqlhelp推荐(已解决 - 请参阅帖子末尾的解决方案)。

我正在尝试加速插入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

1 个答案:

答案 0 :(得分:5)

据我所知,你正在读取平面文件中的29,000,000行并将它们写入临时表,然后运行一个sql脚本,在登台表中更新(读/写)相同的29,000,000行,然后移动那些29,000,000行记录(从分段读取然后写入nat)到最终表。

无法从平面文件中读取数据,使用SSIS transfomations清理数据并添加两个额外的列,然后直接写入最终表。然后,您只能处理每个不同的数据集一次而不是三个(如果您将读取和写入计为不同的六个),那么您的流程会执行多少次?

我会更改您的数据流以转换处理所需的项目并直接写入我的最终表格。

修改

从您问题中的SQL看来,您正在通过从PHONE字段中删除逗号来转换数据,然后从当前处理的文件所在的文件路径的特定部分检索STATE和Date,然后存储这些三个数据点进入NAT表。这些事情可以通过数据流中的派生列转换完成。

对于State和Date列,设置两个名为State和Date的新变量。使用变量定义中的表达式将它们设置为正确的值(就像在SQL中一样)。当Path变量更新时(在你的循环中,我假设)。 State和Date变量也会更新。

在“派生列转换”中,将“状态变量”拖动到“表达式”字段中,然后创建一个名为“状态”的新列。

重复日期。

对于PHONE列,在Derived Column transforamtion中创建如下表达式:

REPLACE([电话],“,”,“”)

将派生列字段设置为替换'电话'

对于输出,请为NAT表创建目标,并将数据流中的“电话”,“状态”和“日期”列链接到NAT表中的相应列。

如果您的输入中有其他列,您可以选择不从源中提取这些列,因为您似乎只是在原始数据的“电话”列中操作。

<强> /修改