4

此处由 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
4

1 回答 1

5

据我了解,您正在从平面文件中读取 ~ 29,000,000 行并将它们写入暂存表,然后运行一个 sql 脚本更新(读取/写入)暂存表中相同的 29,000,000 行,然后移动这 29,000,000 条记录(读取从登台然后写入 nat) 到决赛桌。

难道你不能从你的平面文件中读取,使用 SSIS 转换来清理你的数据并添加你的两个额外的列,然后直接写入最终表。然后,您只会对每个不同的数据集处理一次,而不是您的进程执行的三个(如果将读取和写入视为不同,则为六个)次?

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

编辑

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

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

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

重复日期。

对于 PHONE 列,在派生列转换中创建如下表达式:

替换([电话],“,”,“”)

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

对于您的输出,为您的 NAT 表创建一个目标,并将数据流中的 Phone、State 和 Date 列链接到 NAT 表中的相应列。

如果您的输入中有其他列,您可以选择不从源中引入它们,因为您似乎只对原始数据中的电话列进行操作。

/编辑

于 2012-11-19T22:00:43.817 回答