我有一个ssis包,我使用sql作业运行,用于将数据从一个数据库批量复制到另一个数据库。目的地是我们的集成服务器,我们有足够的空间存放数据库。但是,当我运行这个工作(即包)。它在localsettings / temp文件夹中创建了大量的临时文件,按1GB mdf文件的顺序创建了大约20GB的临时文件。我手动创建了这个包,并没有使用导入导出向导。任何人都可以帮助我在执行时如何避免这种巨大的临时文件?如果需要进一步的细节,请提及。
注意:很多人说如果我们使用导入导出向导创建一个包并为许多表设置优化,则会发生这种情况。但是在这个包中,我只查询一个表并且手动创建而不使用导入导出向导。
答案 0 :(得分:6)
SSIS是一种内存中的ETL解决方案,除非它无法将所有内容保存在内存中并开始交换到磁盘。
完全和部分阻止转换会强制数据流中的内存副本。假设您有10个桶,每个桶携带1MB数据。当您使用阻塞转换时,当这些存储桶到达转换时,必须将数据从一个内存位置复制到另一个内存位置。你现在已经将你的软件包总内存消耗量翻了一倍,因为你在union all转换之前使用了10MB的数据,然后是10MB的数据。
仅使用您需要的列。如果列不在目标中,请不要将其添加到数据流中。使用数据库执行排序和合并。在数据流到数据流之前,将数据转换为适当的类型。
查找转换。我看到人们在使用SELECT * FROM dbo.BillionRowTable
时会破坏他们的ETL服务器,因为他们只需要当前时间段的一列或两列。查找操作的默认行为是执行该源查询并将结果缓存在内存中。对于宽大和/或深度的大型表,这可能使您的数据流看起来甚至没有运行,因为SSIS忙于流式传输并将所有数据作为预执行阶段的一部分进行缓存。
二进制/ LOB数据。在源表中有(n)varchar(max)/ varbinary(max)或经典BLOB数据类型?对不起,那不会在记忆中。相反,数据流将携带一个指针,并为每个对象写出一个文件。
并行处理太多。 SSIS非常棒,因为您可以自由地平行化。除了你可以有太多好事。如果您有20个数据流全部浮动在空间中而它们之间没有优先级,则Integration Services引擎可能会尝试一次运行所有这些数据流。在它们之间添加优先约束,即使它刚刚完成(成功/失败时)以强制某些序列化操作。在数据流中,您可以通过执行不相关的操作来引入相同的挑战。我的经验法则是从任何来源或目的地开始,我应该能够到达所有其他来源/目的地。
检查盒子上还有什么内存。 Have you set a sane (non-default) maximum memory value for SQL Server?像胖孩子一样喜欢RAM的SSIS喜欢蛋糕,所以你需要平衡SSIS对数据库本身的内存需求 - 它们有完全独立的内存空间。
每个数据流都能够设置[BufferTempStoragePath和BlobTempStoragePath 2。利用这一点并将其放在具有足够存储空间的驱动器上
最后,添加更多内存。如果你不能通过上面的方法使包更好,那就扔掉更多的硬件并完成。
答案 1 :(得分:4)
如果您获得了那么多临时文件,那么您的数据流中可能会有很多阻塞变换。尝试消除以下类型的转换:聚合,模糊分组,模糊查找,行抽样,排序,术语提取。此外,部分阻塞事务可能会产生相同的问题,但不会产生相同的问题:数据挖掘查询,合并,合并连接,数据透视,术语查找,全联盟,未传输。您可能希望尝试最小化这些转换。
问题可能是数据流中某处的排序转换(这是最常见的)。您可以通过在SQL语句中使用ORDER BY子句来消除此问题。只记得在数据源中设置sorted属性。