我有一个在表格中构建树型结构的过程。然后,一旦构建了树,就会运行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作为选项。
有什么想法吗?
答案 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中并行运行该程序,并且看到运行时间与我使用的块数成比例地减少。