4

我有一个 ssis 包,我使用 sql 作业将数据从一个数据库批量复制到另一个数据库。目的地是我们的集成服务器,我们有足够的空间用于数据库。但是当我运行这个工作(即包)时。它会在 localsettings/temp 文件夹中创建大量临时文件,顺序为 1GB mdf 文件,它会创建大约 20gb 的临时文件。我手动创建了这个包,没有使用导入导出向导。任何人都可以帮助我如何在执行时避免这个巨大的临时文件吗?如果需要任何进一步的细节,请提及。

注意:很多人说,如果我们使用导入导出向导创建一个包并为许多表设置优化,这将会发生。但是在这个包中,我只查询了一个表,并且在不使用导入导出向导的情况下手动创建。

4

2 回答 2

7

为什么包会创建临时文件?

SSIS 是一种内存 ETL 解决方案,除非它不能将所有内容都保存在内存中并开始交换到磁盘。

为什么要像@jeff hornby 建议的帮助那样重组包?

完全和部分阻塞的转换会强制数据流中的内存副本。假设您有 10 个桶,每个桶承载 1MB 的数据。当您使用阻塞转换时,当这些存储桶到达转换时,必须将数据从一个内存位置复制到另一个内存位置。现在,您的程序包总内存消耗翻了一番,因为在 union all 转换之前使用了 10MB 的数据,之后又使用了 10MB。

仅使用您需要的列。如果某个列不在您的目标中,请不要将其添加到数据流中。使用数据库执行排序和合并。在数据进入数据流之前将其转换为适当的类型。

还有什么可能导致临时文件使用

查找转换。我见过人们在使用SELECT * FROM dbo.BillionRowTable当前时间段所需的一两列时粉碎他们的 ETL 服务器。查找操作的默认行为是执行该源查询并将结果缓存在内存中。对于大型和/或深度的大型表,这可能会使您的数据流看起来甚至没有运行,因为 SSIS 正忙于流式传输和缓存所有这些数据作为预执行阶段的一部分。

二进制/LOB 数据。源表中有 (n)varchar(max)/varbinary(max) 或经典 BLOB 数据类型?对不起,这不会在记忆中。相反,数据流将携带一个指针并为每个对象写出一个文件。

并行处理过多。SSIS 很棒,因为您可以免费并行处理您的处理。除非你可以拥有太多的好东西。如果您有 20 个数据流都在空间中浮动且它们之间没有优先级,则集成服务引擎可能会尝试一次运行所有这些数据流。在它们之间添加一个优先约束,即使它只是在完成时(成功/失败时)强制一些操作序列化。在数据流中,您可以通过进行不相关的操作来引入相同的挑战。我的经验法则是,从任何来源或目的地开始,我应该能够到达所有其他来源/目的地。

我还可以做些什么?

检查盒子上还有什么正在使用内存。您是否为 SQL Server 设置了合理的(非默认)最大内存值?SSIS 之类的 RAM 就像一个胖孩子喜欢蛋糕一样,因此您需要平衡 SSIS 的内存需求与数据库本身——它们具有完全独立的内存空间。

每个数据流都可以设置 [BufferTempStoragePath 和 BlobTempStoragePath 2。利用这一点并将其放在具有足够存储空间的驱动器上

最后,添加更多 RAM。如果您无法通过上述操作使软件包变得更好,请投入更多硬件并完成。

于 2012-08-18T20:06:42.287 回答
4

如果您获得那么多临时文件,那么您的数据流中可能有很多阻塞转换。尝试消除以下类型的转换:聚合、模糊分组、模糊查找、行采样、排序、术语提取。此外,部分阻塞事务可能会产生相同的问题,但规模不同:数据挖掘查询、合并、合并连接、数据透视、术语查找、全部联合、反透视。您可能希望尽量减少这些转换。

问题可能是数据流中某处的排序转换(这是最常见的)。您可以通过在 SQL 语句中使用 ORDER BY 子句来消除这种情况。只需记住在数据源中设置 sorted 属性。

于 2012-08-17T14:52:57.057 回答