【问题标题】:DataFlow task in SSIS is very slow as compared to writing the sql query in Execute SQL task与在执行 SQL 任务中编写 sql 查询相比,SSIS 中的 DataFlow 任务非常慢
【发布时间】:2013-04-24 01:32:44
【问题描述】:

我是 SSIS 新手,有两个问题

  1. 我想将 1,25,000 行从一个表传输到同一个数据库中的另一个表。但是当我使用Data Flow Task 时,会花费太多时间。我尝试使用ADO NET DestinationOLE DB Destination,但性能无法接受。当我在Execute SQL Task 中编写等效查询时,它提供了可接受的性能。为什么会有这么大的性能差异。

    INSERT INTO table1 select * from table2

  2. 根据第一次观察,我改变了我的包裹。它完全由Execute SQL Tasks 组成,带有直接查询或存储过程。如果我可以只使用Execute SQL Task 来解决我的问题,那么为什么会像许多文档和文章所指出的那样使用 SSIS。我已经看到它可靠,易于维护且相对较快。

【问题讨论】:

  • 您是否尝试过将传输分成块,例如一次 10K 行?对于大型单一操作而言,日志记录可能会带来创伤。
  • 在使用数据流任务时,它本身将行数分成10k分区然后插入,这是导致速度变慢的原因吗?
  • 你在 oledb 目的地选择了“快速加载”吗?
  • 是的,我也使用了快速加载。但是在阅读了 billinkc 发布的答案后,我让它保留在所有执行 SQL 任务中,并通过 SQL 代理运行它。我现在很满意!
  • 虽然这是一个旧线程,但我最近遇到了这个问题。我的“查找”任务在两个系统上与其他两个系统相比执行不佳。可能是下面概述的原因之一,但我通过将所有查找重构为使用 JOINS 和 CTE 组合的 SQL 任务来解决它。我将第一次批量运行的 30 多个小时缩短到 6 小时。巨大的胜利。只有在数据流添加列的地方,我才保留这些列。

标签: sql-server ssis etl


【解决方案1】:

性能差异

有许多事情可能会导致“直接”数据流任务和等效的执行 SQL 任务的性能。

  1. 网络延迟。您正在同一服务器和实例上从表 b 插入表 a。在执行 SQL 任务中,该工作将完全在同一台机器上执行。我可以在服务器 B 上运行一个包,从服务器 A 查询 125 万行,然后通过网络将这些行流式传输到服务器 B。然后,该数据将流式 返回 到服务器 A 以进行相应的 INSERT 操作.如果你的网络很差,数据很宽,尤其是二进制类型,或者服务器之间的距离很远(服务器 A 在美国,服务器 B 在印度),那么性能就会很差
  2. 内存不足。假设包在与目标/源数据库相同的服务器上执行,它仍然可能很慢,因为数据流任务是一个内存引擎。这意味着,将从源流向目标的所有数据都将进入内存。 SSIS 可以获得的内存越多,运行速度就越快。但是,它将不得不与操作系统争夺内存分配以及 SQL Server 本身。即使 SSIS 是 SQL Server 集成服务,它也不会在与 SQL Server 数据库相同的内存空间中运行。如果你的服务器分配了 10GB 内存,而操作系统使用 2GB,而 SQL Server 声称有 8GB,那么 SSIS 运行的空间很小。它不能要求 SQL Server 放弃部分内存,因此操作系统将不得不在细流数据通过狭窄的数据管道移动时进行分页。
  3. 劣质目的地。根据您使用的 SSIS 版本,OLE DB 目标的默认访问模式是“表或视图”。这是一个很好的设置,可以尝试防止低级锁升级为表锁。但是,这会通过痛苦的行插入(发送 125 万个唯一插入语句)导致行。将其与Execute SQL Tasks INSERT INTO 的基于集合的方法进行对比。较新版本的 SSIS 将访问方法默认为目标的“快速”版本。这将更像基于集合的等效项,并产生更好的性能。
  4. OLE DB 命令转换。有一个OLE DB Destination,有些人将它与OLE DB Command Transformation 混淆了。这是两个具有不同用途的非常不同的组件。前者是一个 destination 并消耗所有数据。它可以非常快。后者是总是 RBAR。它将对流经它的 每个 行执行单例操作。
  5. 调试。在 BIDS/SSDT 中运行包存在开销。该包执行被包装在 DTS 调试主机中。这可能会导致包执行的“不显着”减慢。调试器对执行 SQL 任务无能为力——它运行或不运行。一个数据流,它可以检查、监视大量内存等,这会减少可用内存量(参见第 2 部分),并且由于它正在执行的各种检查而减慢它的速度。要获得更准确的比较,请始终从命令行 (dtexec.exe /file MyPackage.dtsx) 运行包或从 SQL Server 代理安排它。

包装设计

只有Execute SQL Tasks 的 SSIS 包本质上没有任何问题。如果问题很容易通过运行查询来解决,那么我会完全放弃 SSIS 并编写适当的存储过程并使用 SQL 代理安排它并完成。

也许吧。即使对于像这样的“简单”案例,我仍然喜欢使用 SSIS 的原因是它可以确保一致的可交付成果。这听起来可能不多,但从维护的角度来看,很高兴知道与数据混在一起的所有内容都包含在这些源代码控制的 SSIS 包中。我不必记住或培训新人任务 A-C 是“简单的”,因此它们是从 SQL 代理作业调用的存储过程。任务 D-J,或者它是 K,甚至比这更简单,所以它只是代理作业中的“在线”查询以加载数据,然后我们为其余的东西准备了包。除了 Service Broker 和一些 Web 服务之外,它们也会更新数据库。我年纪越大,接触的地方越多,我就越能在一致的(即使是矫枉过正的)解决方案交付方法中找到价值。

性能并不是一切,但 SSIS 团队确实使用 SSIS 设置了 ETL 基准,因此它绝对有能力快速推送一些数据。

随着这个答案越来越长,我会简单地将其保留为 SSIS 的优势和直接 TSQL 上的数据流是原生的,开箱即用

  • 日志记录
  • 错误处理
  • 配置
  • 并行化

为了我的钱很难打败那些。

【讨论】:

  • 感谢您提供如此清晰的解释和解决方案。非常感谢。
  • 我已经完成了 SSIS,但是当我从 sql server 安排它时,它无法执行,请查看此链接以获取我的帖子。 stackoverflow.com/questions/16766416/…
【解决方案2】:

如果您在参数映射选项卡中将 SSIS 变量作为参数传递并通过表达式将值分配给这些变量,那么您的执行 SQL 任务会在评估该表达式时消耗大量时间。 使用表达式任务(单独)分配变量,而不是在变量选项卡中使用表达式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    相关资源
    最近更新 更多