【问题标题】:C# Handle Batch Wise Database Querying with Parallel ForC# 使用 Parallel For 处理批量数据库查询
【发布时间】:2018-10-14 03:07:31
【问题描述】:

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

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。所以在下一次调用中,会返回新批次。

但现在我想在 parallel for 中执行此 SP 调用。 现在我想这样实现它。

parallelfor
{
 UpdateBatch(SpCall());
}

但我不能使用“TOP”,因为 SP 调用并行发生(因此 tableA_modified 未设置为前 1000 行中的 0)。而且我也不能获取整个结果(不将第一组限制为 1000),因为这会产生超时。有没有办法解决这个问题。

【问题讨论】:

  • 您可以尝试在 SQL 中使用页面/偏移量,但请确保您可以订购一些安全的东西。 dofactory.com/sql/order-by-offset-fetch 并将页码传递给存储过程。您仍然需要弄清楚每次调用是针对哪个页面的。
  • 您需要计算总行数,然后在 c# 中创建与批次相关的范围,然后将范围传递到 parallel.foreach。然后有一个 SP,它将返回一系列条目,order byid columnwhere,范围为 start > yx < end。这意味着选择查询仍将保持高性能,并且永远不会选择相同的行。理想情况下,您希望向表中添加一列并将其命名为批处理,并预先分配一个 batch_id,并据此进行处理。

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


【解决方案1】:

如果您可以向 tableA 添加一列(例如 UpdateBatchId),则可以更新过程以接收将在前 1000 行上设置的 @UpdateBatchId 参数(使用相同的 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 表中并使用其中的标识列作为 UpdateBatchId 参数到更新),那么 SpCall 就不需要来了更新并传递 UpdateBatchId。

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

【讨论】:

  • 我想在不改变数据库结构的情况下实现这个(不添加新表或新列)
  • tableA_id 是连续标识列,间隔最小或没有间隔吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多