我在数据库表中有一百万行。对于每一行,我必须运行自定义exe,解析输出并更新另一个数据库表
如何并行处理多个行?
我现在有一个简单的数据流任务 - > GetData->运行脚本(运行流程,解析输出) - >存储数据 6000行需要3个小时。太多了。
答案 0 :(得分:3)
这里存在单一瓶颈,每行运行一次流程。增加“EngineThreads”根本没有用,因为无论如何只有一个线程运行这个特定的脚本转换。在其他变换中花费的时间可能根本不重要。进程是重量级的对象,运行数以千计的对象永远不会便宜。
我可以想到以下想法,以使其更好:
1)修复它的最好方法是将自定义EXE转换为程序集并从脚本转换中调用它 - 以避免创建进程,解析输出等的开销。
2)如果必须使用单独的进程,则可以尝试并行运行这些进程。如果进程主要等待某些输入/输出(即它是I / O绑定),它将有所帮助。如果进程是内存绑定或CPU绑定的,那么通过并行运行它们就不会赢得太多。
2A)复杂的脚本,简单的包。
要并行运行它们,请修改脚本中的ProcessInput方法以异步方式启动进程,并且不要等待进程完成 - 转到下一行并创建下一个进程。订阅流程输出并处理退出事件,以便您知道它何时完成。限制并行运行的进程数 - 否则你将耗尽内存。等到所有进程完成后再从ProcessInput调用返回。
2B)简单的脚本,复杂的包。
保留当前的顺序脚本,但使用SSIS对数据进行分区。添加条件分割变换,并根据一些散列表达式将输入流拆分为多个流 - 这将使每个输出接收大致相同数量的数据。流的数量等于要并行运行的流程实例的数量。将脚本转换添加到条件拆分的每个输出。现在你还应该增加“引擎线程”属性:)并且这些转换将并行运行。 (注意:基于标记,我假设您使用SSIS 2008.您需要插入其他Union Union转换以使其在SSIS 2005中有效。)
这应该会让它表现更好,但数百万个流程很多。你在这里很难得到很好的表现。
答案 1 :(得分:1)
如果您正在使用“数据流”容器执行此过程,那么它上面有一个名为“EngineThreads”的属性,其默认值为5.您可以将其设置为更高的数字,如20,这将投入处理这些行的更多线程。
这只是性能调整或选择,如果你的ssis软件包仍然运行得非常慢,那么我可能会解决你的软件包的架构和设计。