2

我有一个在表中构建树型结构的过程。然后,一旦构建了树,就会运行更新语句以根据表中的其他列(在过程的树创建部分期间创建的)更新表中的 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 毫秒,我们调用它数十万次(这就是表中存在的行数)。过去大约需要 90 毫秒,因此我们已经大大提高了函数的性能。该函数本质上相当复杂,但我在此示例中抽象出复杂性。更新后的表格示例。

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

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

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

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

有什么想法吗?

4

1 回答 1

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 中并行运行该过程,并且看到运行时间与我使用的块数成正比减少。

于 2013-10-02T18:20:52.930 回答