SSIS增量负载

时间:2013-03-22 00:55:31

标签: sql-server ssis

我试图在不稳定的线路上使用SSIS包传输大约10亿行。因此,它一直在失败。我想要一些让它可以重启的方法。我试图在源和目标之间进行查找转换,但这样做太慢了。还有另一种方法可以做我想要做的事情而不会受到如此影响吗?

2 个答案:

答案 0 :(得分:2)

我最初的方法是编写一个包,它在启动时识别要传输的数据的子集,记录它正在处理的子集并尝试传输该数据。如果它完成,则它将数据标记为已传输并退出。否则,它已经被炸毁了,那个包没有什么可做的。

另一个进程将运行X时间帧并尝试查找失败的传输(标记为进程但超过Y持续时间的子集)。然后,它会从转移表中删除这些行,或将它们标记为符合转移条件。一般的想法是,破坏的东西被标记为重建。

这是一个非常简单的设计,最难的部分是分段和跟踪已经/未传输的内容,然后只需设置一个SQL代理作业,每N个时间帧触发一次。如果不是你的网络有问题,那么做这样的数据传输是一件好事,它允许你并行化你的执行,以便获得最大的吞吐量。 SSIS团队在设置record加载数据时采用了类似的方法。他们也从系统中走出了地狱,但这也是预期的。

如果1B行系统正在进行大量更新,那么您的数据分段逻辑将需要一些机制来识别变化并确保将这些记录反馈到系统中,但由于您没有指定需要,我暂时忽略它。

如果您尝试使用查找,请确保您只撤回绝对必要的内容。对于这种情况,我希望这是一个非常狭窄的关键。如果您采用分段数据加载方法,那么请确保在查找转换中使用相同的分区逻辑。否则,你将在最后一次运行时撤回(1B -1 * transferSize)数据行,这无疑会对你的伪劣网络造成严重破坏。

如果你想要更多关于方面的细节,可以唱出很多的一般性。

答案 1 :(得分:1)

是否值得一次做一百万行这样的事情

DECLARE @Counter Int, @ReturnCode Int
DECLARE @Rows INT = 1000000, @Goal INT = 1000000000
  WHILE (@Counter * @Rows < @Goal)
    BEGIN
      EXEC @returncode = xp_cmdshell 'dtexec /f "C:\\path\\package.dtsx" /SET \\package.variables [User::Counter].Value;"' + CONVERT(VARCHAR(10), @Counter) + '"'

      IF (@returncode = 0)
        BEGIN
          @Counter = @Counter + 1
          PRINT 'Failed this at this time dude: ' + CONVERT(VARCHAR(30), GETDATE())
        END
    END

然后在查询中的oledb源代码组件中有一个where子句,如

    WHERE TableID BETWEEN (SELECT MIN(TableID) FROM Table) + ((? - 1) * 1000000)) 
          AND (SELECT MIN(TableID) FROM Table) + (? * 1000000))

虽然有几件事 - 我认为你必须在SSIS变量的表达式中构建查询(之前你曾经做过吗?很容易,有时会使用子查询中的参数给出错误)你可能应该在开头只抓一次MIN(TableID)并将其存储在变量中。

这一切都值得这么麻烦,你认为这会有所帮助吗?