【问题标题】:How to use for each loop to help load large dataset如何使用每个循环来帮助加载大型数据集
【发布时间】:2012-05-24 03:41:56
【问题描述】:

我正在尝试从 SSIS 中的 SQL Server 2008 加载大型数据集。但是,Visual Studio 一次加载所有内容太慢了。然后我决定使用 for-each 循环每次只加载表的一部分。

例如如果有 1000 万条记录,我希望每次加载 100 万条,运行 10 次即可完成处理。

这只是我的“大脑设计”,我不知道如何使用 Foreach 循环组件来制作它。有没有其他方法来处理大型数据集?

【问题讨论】:

  • 是否需要同时将整个数据集加载到内存中?或者你可以让它批量流过数据流吗?如果您的批处理设置正确,SSIS 在后者方面表现出色。

标签: ssis large-data-volumes foreach-loop-container


【解决方案1】:

要讨论的变量太多了,我要在 5 分钟内开会。

你说它很慢。 什么很慢?如果不知道这一点,您可能会一直在追逐错误的兔子。

SSIS 在 2008 年凭借 ETL processing speed by loading 1TB in 30 minutes 夺得桂冠。当然,他们从系统中调整了每一个有爱心的人来让它这样做,但他们详细列出了他们采取的步骤。

1000 万行,虽然听起来很大,但我不会考虑对 SSIS 征税。首先,查看您的目标对象(假设为 OLEDB)。如果它没有选中 Fast Load 选项,您将发出 10M 单插入语句。这将淹没您的事务日志。还要查看提交大小中的行数。 0 表示全有或全无,根据您的可恢复性,这可能是正确的决定,也可能不是正确的决定,但确实意识到对您的事务日志的影响(它会占用相当多的空间)。

您对管道中的数据应用了哪些转换?有些转换会扼杀您的吞吐量(排序、聚合等)

创建一个基线包,它所做的只是从源位置读取 N 行数据并执行行计数。这对于理解给定硬件的最佳理论吞吐量至关重要。

在 Visual Studio/BIDS/SSDT 中运行包的速度较慢,有时比通过 SQL Agent/dtexec 调用所获得的体验慢一个数量级,因为它不会将执行包装在调试器中。

我有时间会修改这个答案,但这些是一些初步的想法。我会在会后发布关于使用 foreach 循环任务处理离散数据块的文章。

【讨论】:

    【解决方案2】:

    我认为最好的方法是对数据进行功能分区。在大多数情况下,日期列适合执行此操作。我们以订单日期为例。

    对于该列,找到最佳分母,例如,您的订单日期每年产生大约一百万行。

    使用for loop container 代替每个循环容器。

    要使此循环正常工作,您必须在源数据中找到所有订单日期的最短和最长年份。可以使用将标量结果保存到 SSIS 变量中的 SQL 语句来检索这些。

    接下来,将您的 for 循环容器设置为在您之前存储在变量中的最小和最大年份之间循环,每次迭代增加一年。

    最后,要真正检索您的数据,您必须将源 SQL 语句保存为变量中的表达式,其中带有一个 where 子句,该子句指定您的 for 循环容器产生的当前年份:

    "SELECT * FROM transactions WHERE YEAR(OrderDate) = " + @[User::ForLoopCurrentYear]
    

    现在您可以在数据流源中使用此变量来检索分区数据。

    编辑:

    使用 for each 循环容器的不同解决方案是使用执行 SQL 任务检索分区键并将结果集保存在类型为 Object 的 SSIS 变量中:

    SELECT YEAR(OrderDate) FROM transaction GROUP BY YEAR(OrderDate)
    

    使用 for each 循环容器,您可以使用 ADO 枚举器遍历对象,并使用与上述相同的方法将当前年份注入源 SQL 语句。

    【讨论】:

    • 感谢您的回答!我每次都需要将所选数据与其他一些表合并,这就是我必须为每个循环使用的原因。否则,处理速度会更慢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多