C#处理批量明智数据库并行查询

时间:2018-10-14 03:07:32

标签: c# sql-server task-parallel-library parallel-foreach

我有一个非并行数据查询存储过程调用。这是查询。

SELECT TOP(1000) a.[tableA_id] AS [id],a.[tableA_name],a.[tableA_modified]
FROM tableA a
WHERE a.[tableA_modified] = 1
    AND a.tableA_id NOT IN (
        SELECT tableA_id_foreign
        FROM tableB_id b
    )

这是C#代码的样子。

for
{
  UpdateBatch(SpCall());
}

此SP调用批量执行。在成功完成批处理之后,将“ tableA_modified”列设置为该批的0。因此,在下一个调用中,将返回新批次。

但是现在我想在常见问题中执行此SP调用。 现在,我要像这样实现它。

parallelfor
{
 UpdateBatch(SpCall());
}

但是我不能使用'TOP',因为SP调用是并行进行的(因此tableA_modified未设置为前1000行的0)。而且我也不能接受整个结果(不将第一组限制为1000),因为那样会造成超时。有没有解决的办法。

1 个答案:

答案 0 :(得分:0)

如果您可以向tableA添加一列(例如UpdateBatchId),则可以更新该过程以接收@UpdateBatchId参数,该参数将在前1000行中设置(使用相同的where条件以及其他条件,以包括空的UpdateBatchId)。然后它将返回使用该特定UpdateBatchId设置的记录:

UPDATE TOP(1000) SET a.UpdateBatchId = @UpdateBatchId
OUTPUT inserted.[tableA_id] AS [id], inserted.[tableA_name], inserted.[tableA_modified]
FROM tableA a
WHERE a.[tableA_modified] = 1
AND a.tableA_id NOT IN (
    SELECT tableA_id_foreign
    FROM tableB_id b
)
AND a.UniqueBatchId is null 

然后在SpCall中传递新的唯一更新批次ID。可以从代码(例如Guid之类)中得出:

parallelfor
{
 UpdateBatch(SpCall(GetNewUniqueUpdateBatchId()));
}

UpdateBatchId也可以来自另一个表(例如包含UpdateBatch数据的表)的标识列。如果使用表和标识列,则查询也可以处理该部分(将一行插入UpdateBatch表中,并将该标识列用作Update的UpdateBatchId参数),则SpCall不需要并通过UpdateBatchId。

如果无法向表中添加列,则可以对具有两列tableA_id和UpdateBatchId的新表执行类似的操作。