我有一个SSIS包--两个数据流任务,每个组件8个,从两个平面文件中读取,没有什么了不起的。如果我在投标中运行它,它需要可靠的大约60秒。我有一个沙箱DB服务器,包运行在一个作业中,这也需要30到60秒的可靠时间。在我的生产服务器上,使用相同包的同一个任务从30秒到12小时不等。
如果在包上启用了日志记录,它看起来就会陷入停滞--至少一开始--处于一个或另一个数据流任务的预执行阶段。但是我也能看到数据的输入--慢慢地,以小块的形式,所以我认为它以后会继续。IO子系统受到冲击,SSIS生成许多大的临时文件(大约150 my的值--我的输入数据文件加在一起只有24 my),并且正在从这些文件中大量读取和写入文件(乱七八糟?)
值得注意的是,如果我将包的出价实例指向生产服务器,仍然只需大约60秒即可运行!所以一定是在那里运行dtexec,而不是DB本身。
我已经尝试优化我的包,减少输入行字节大小,并且我使两个数据流任务以串联方式运行,而不是并行运行--都是徒劳的。
两个DB服务器都运行MSSQL 2008 R2 64位,补丁级别相同.这两台服务器都是同一台主机上的VM,具有相同的资源分配。生产服务器上的负载不应该比沙箱服务器现在高得多。我看到的唯一不同是生产服务器正在运行Windows 2008,而沙箱位于Windows 2008 R2上。
救命!任何尝试的想法都是受欢迎的,是什么导致了这个巨大的差异?
附录A
这是我的包裹看起来像…
控制流非常简单:
数据流如下所示:
第二个数据流任务完全相同,只是具有不同的源文件和目标表。
备注
控制流中的完成约束仅用于使任务连续运行,以尝试同时减少所需资源(而不是帮助解决问题)…这两个任务之间没有实际的依赖关系。
我知道阻塞和部分阻塞转换的潜在问题(不能说我完全理解它们,但至少在某种程度上),并且我知道聚合和合并连接是阻塞的,可能会导致问题。但是,除了生产服务器…之外,所有这些都在其他所有环境中都运行良好和快速。那是怎么回事?
合并连接的原因是让任务等待多播的两个分支完成。右分支在输入中找到最短的日期时间,并在该日期之后删除表中的所有记录,而左分支携带新的输入记录以供插入--因此,如果右分支在聚合和删除之前继续进行,新记录将被删除(这种情况发生了)。我不知道有更好的方法来处理这件事。
来自"Delete记录“的错误输出始终是空的--这是故意的,因为我实际上不希望在合并中从该分支中出现任何行(合并只是为了同步完成,如上面所解释的那样)。
请参阅下面关于警告图标的注释。
发布于 2013-12-24 14:55:22
如果已打开日志记录,最好是打开Server,则添加OnPipelineRowsSent事件。然后,您可以确定它所有的时间都花在哪里。请参阅此帖子,您的IO子系统被关闭并生成所有这些临时文件,这是因为您不再能够将所有信息保存在内存中(因为您的异步转换)。
链接文章中的相关查询如下。它查看sysdtslog90
( Server 2008+用户替代sysssislog
)中的事件,并对它们执行一些时间分析。
;
WITH PACKAGE_START AS
(
SELECT DISTINCT
Source
, ExecutionID
, Row_Number() Over (Order By StartTime) As RunNumber
FROM
dbo.sysdtslog90 AS L
WHERE
L.event = 'PackageStart'
)
, EVENTS AS
(
SELECT
SourceID
, ExecutionID
, StartTime
, EndTime
, Left(SubString(message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, 56) + 1) + 1) + 1) + 2, Len(message)), CharIndex(':', SubString(message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, CharIndex(':', message, 56) + 1) + 1) + 1) + 2, Len(message)) ) - 2) As DataFlowSource
, Cast(Right(message, CharIndex(':', Reverse(message)) - 2) As int) As RecordCount
FROM
dbo.sysdtslog90 AS L
WHERE
L.event = 'OnPipelineRowsSent'
)
, FANCY_EVENTS AS
(
SELECT
SourceID
, ExecutionID
, DataFlowSource
, Sum(RecordCount) RecordCount
, Min(StartTime) StartTime
, (
Cast(Sum(RecordCount) as real) /
Case
When DateDiff(ms, Min(StartTime), Max(EndTime)) = 0
Then 1
Else DateDiff(ms, Min(StartTime), Max(EndTime))
End
) * 1000 As RecordsPerSec
FROM
EVENTS DF_Events
GROUP BY
SourceID
, ExecutionID
, DataFlowSource
)
SELECT
'Run ' + Cast(RunNumber As varchar) As RunName
, S.Source
, DF.DataFlowSource
, DF.RecordCount
, DF.RecordsPerSec
, Min(S.StartTime) StartTime
, Max(S.EndTime) EndTime
, DateDiff(ms, Min(S.StartTime)
, Max(S.EndTime)) Duration
FROM
dbo.sysdtslog90 AS S
INNER JOIN
PACKAGE_START P
ON S.ExecutionID = P.ExecutionID
LEFT OUTER JOIN
FANCY_EVENTS DF
ON S.SourceID = DF.SourceID
AND S.ExecutionID = DF.ExecutionID
WHERE
S.message <> 'Validating'
GROUP BY
RunNumber
, S.Source
, DataFlowSource
, RecordCount
, DF.StartTime
, RecordsPerSec
, Case When S.Source = P.Source Then 1 Else 0 End
ORDER BY
RunNumber
, Case When S.Source = P.Source Then 1 Else 0 End Desc
、DF.StartTime,Min(S.StartTime);
您可以使用此查询识别合并连接组件是滞后组件。为什么它在这两个服务器之间执行不同,我现在还不能说。
如果您能够在目标系统中创建一个表,您可以修改您的流程,使其有两个数据流(并消除代价高昂的异步组件)。
发布于 2013-12-20 14:54:01
下面的步骤将有助于提高SSIS性能。
https://stackoverflow.com/questions/20606292
复制相似问题