【问题标题】:SSIS - execute N concurrent instances of the same taskSSIS - 执行同一任务的 N 个并发实例
【发布时间】:2015-03-11 15:57:30
【问题描述】:

我目前正在处理一个 SSIS 包。它的作用是运行相同的 SQL 语句 10 次,每次使用不同的参数 N 值(N 从 0 到 9)。语句是相互独立的(它们只是 INSERT INTO ... SELECT * FROM ... WHERE some_int_column % 10 = N)。

我当前的实现非常幼稚:我用 10 个不同的 N 值创建了同一个 .sql 文件的 10 个副本,然后创建了 10 个单独的“执行 SQL”任务,并将每个任务指向不同的 SQL 文件。

这很好用。但现在我需要能够动态改变 N 的最大值,即创建 Nmax 个并行任务,每个任务都有不同的参数值(从 0 到 Nmax-1)。

我应该如何处理这个问题?我在考虑一个 FOR 循环,但你不能在 SSIS 中获得一个异步 FOR 循环,所以这行不通。还有其他想法吗?

我使用的是 SQL Server 2008 R2。

【问题讨论】:

  • 不必在 SSIS 中,也不必在循环中完成。您应该能够修改您的过程,以便它以基于集合的方式使用@n
  • 是的...但是,我不想。我正在从限制单个会话吞吐量的链接服务器加载数据,因此我需要多个并发加载任务,因此请克服此限制。

标签: sql-server sql-server-2008 parameters ssis parallel-processing


【解决方案1】:

我可能会使用脚本组件来做到这一点。

它将包含一个从 1 到 N 的循环 并调用

SqlCommand.BeginExecuteNonQuery

这是异步的(即立即返回)。

这将提供您需要的并行性。

【讨论】:

  • 很好的建议(+1!),请记住与EndExecuteNonQuery 结合使用。另外,我认为每个命令对象只能执行一次BeginExecuteNonQuery,直到调用结束,因此要实现并行性,您也必须生成 N 个命令对象。
  • ExecuteNonQueryAsync 可能会更好?
  • 听起来很聪明。我会试一试并很快恢复。在此之前,我会将您的答案标记为最佳答案。谢谢!
  • @gvee 提出了一个有效的观点。 ExecuteNonQueryAsync 可能会更好(也更简单)。
  • 过去几个小时我一直在测试这种方法,它似乎工作得很好。问题已解决 - 谢谢 Mike!
【解决方案2】:

在 SQL 中,我们尽一切努力避免循环。

我们在集合中思考。

假设您现有的程序如下所示:

ALTER PROCEDURE some_procedure (
   @n int
)
  AS
BEGIN
  SET NOCOUNT ON;

  INSERT INTO something (column_list)
  SELECT column_list
  FROM   something_else
  WHERE  some_int_column % 10 = @n
  ;
END
;

这是一个非常微小的变化,看看你能不能发现它!

ALTER PROCEDURE some_procedure (
   @n int
)
  AS
BEGIN
  SET NOCOUNT ON;

  INSERT INTO something (column_list)
  SELECT column_list
  FROM   something_else
  WHERE  some_int_column % 10 <= @n
  ;
END
;

你看到了吗? = @n 变成了&lt;= @n

考虑您要为@n=0@n=3 执行此操作。在第一个过程中,我们会这样做:

EXEC some_procedure @n=0;
EXEC some_procedure @n=1;
EXEC some_procedure @n=2;
EXEC some_procedure @n=3;

但随着更新,我们可以这样做:

EXEC some_procedure @n=3;

关于并行性的更新:

不幸的是,SSIS 目前在 ForEach 循环中不包含这种功能。这已在过去作为 Connect 项目提出 (https://connect.microsoft.com/SQLServer/feedback/details/544304/ssis-parallel-foreach-loop),但看起来不会很快出现。

据我所知,您还有两个选择:

  1. 在 SSIS 中创建X ForEach 循环任务并让它们处理它们之间的@n%X 任务。显然,这意味着您只能获得与创建的任务数量一样多的并行度。
  2. 推出您自己的托管代码解决方案,该解决方案可以产生自己的线程。

不是你要找的答案,但你这些是我现阶段能想到的所有选择!


对不起,我知道这不是最好的解释,所以如果有不清楚的地方,请在 cmets 中提出任何您想要的内容,我会尝试改进我的答案!

【讨论】:

  • 感谢您教我 SQL!信不信由你,我确实在集合中思考。多年来,我一直在使用 SQL 数据库,我知道循环、游标等的所有注意事项。但是对于这个特定的任务,并行化负载会使事情变得更快(从 140 分钟缩短到 20 分钟),原因不在本文讨论范围内。
  • @xpil 不幸的是,在 SSIS 中循环不会给你并行性,因为任务将有效地排队!但是,您可能会从小批量处理的结果中获得性能提升?一种解决方法可能是创建 X 个任务(其中 X=可用并行线程的数量),然后让每个任务执行 @n%X 任务?
  • 是的,这正是我想要实现的目标,只是我希望 X 成为一个变量,而不是一个常量。
  • @xpil 不幸的是,我对如何在 SSIS 中实现这一点感到有些困惑。您可能可以使用一些生成自己的线程的托管代码来做到这一点,但 SSIS 本身并不是动态的。 Parallel ForLoop 容器之前已经通过 MS 提出 (connect.microsoft.com/SQLServer/feedback/details/544304/…),但看起来不会很快出现。
  • 好的 gvee,非常感谢 - 我将把它作为目前最好的答案。祝你有美好的一天!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多