T-SQL将更新语句拆分为并行块

时间:2013-10-02 13:06:41

标签: sql tsql ssis sql-server-2008-r2 parallel-processing

我有一个在表格中构建树型结构的过程。然后,一旦构建了树,就会运行update语句,以根据表中的其他列(在过程的树创建过程中创建)更新表中的1列。因此,更新中没有加入其他表。一切都可以在表格中逐行完成。表的示例(更新前)如下所示。

DrillPath    TimePeriod    CellValue
1            1             NULL
1,2          1             NULL
1,3          1             NULL
1            2             NULL
1,2          2             NULL
1,3          2             NULL

因此更新语句看起来像这样。

update table set CellValue = dbo.SomeLongRunningFunction(DrillPath, TimePeriod)

函数dbo.SomeLongRunningFunction()表每次调用运行大约5毫秒,我们称之为数十万次(表中存在多少行)。它过去需要大约90ms,所以我们已经大大提高了功能的性能。该函数本质上相当复杂,但我在这个例子中抽象出复杂性。更新后的表格示例。

DrillPath    TimePeriod    CellValue
1            1             5.1
1,2          1             3.2
1,3          1             NULL (NULL can be a valid answer)
1            2             1.0
1,2          2             2.5
1,3          2             8.1

我想将此更新“chunk”为5(或在一般情况下x并行更新),每个操作在行的子集上。 with (rowlock)提示可能用于确保不会发生死锁,因为每个“块”将更新它自己的行,而“块”将永远不会相交。

我的第一个应用程序是SSIS并且并行运行存储过程5次并传递低/高范围以进行更新。然而,似乎只有1个程序在任何给定时间实际更新,而其他程序正在等待。这使我相信即使使用with (rowlock)进行更新,update语句也会锁定整个表。我知道只有1正在运行,因为我可以从查询窗口中的表中进行选择,并查看已更新的记录数。如果我将工作分成5个流程,那么记录的数量并没有按照我期望的速度增加。

我正在寻求有关如何并行运行这些更新的任何其他方法和建议。我需要在安全的环境中保持“开箱即用”SQL Server 2008 R2企业版的范围(没有xp_cmdshell,如果没有其他选项,可能是CLR函数或自定义程序集)。我也有SSIS作为选项。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

所以我实际上决定在运行更新的过程中使用表变量。

Step 1: insert into the table variable the "chunk" from the real table that I want to update.
Step 2: update the column in the table variable.
Step 3: delete the "chunk" from the real table.
Step 4: insert the table variable rows into the real table.

这消除了锁定的任何问题,而且我的块不够大,无法真正引起内存利用率的任何问题。

我能够在SSIS中并行运行该程序,并且看到运行时间与我使用的块数成比例地减少。