如何获得前X条记录,而又没有多个任务重叠?

时间:2019-03-25 14:36:20

标签: sql sql-server

编辑:如果重要的SQL Server 2012

我们有一个表,其中包含多个针对该表的作业。与每个作业中使用的查询相同。如何避免查询中的锁定和重叠?

我们有正在生产的代码,但是创建它的人不见了,查询中没有解释。

我认为CTE(在查询中)对于此任务很重要,但我一直无法找到可能的解释。我无法正确搜索,因为我发现所有结果在多个线程中都获得了TOP X而不是TOP X,并且没有重叠。

示例表tmp1:

id | processed 
1  | 0
2  | 0
3  | 0
4  | 1
... 

表很大,所以我知道要花一些时间才能运行,这就是为什么我们要分批处理它。

当前查询如下:

WITH tmpIDS AS (
  select top 100 * from tmp1
  where processed = 0
)
INSERT INTO #work (id)
select * from (
 update tmpIDS set processed = 1
output inserted.id
) a;

查询后出现的所有内容要么使用临时表#work,要么使用id并过滤到原始表上的一条记录。

我们无法回答的问题是为什么以这种方式编写此查询。计划有多个作业同时(或足够接近)运行此查询,并且据我们了解,它们没有选择相同的TOP X记录。

我们希望这会导致表锁定并彼此阻塞,但事实并非如此,这意味着它确实在一定程度上起作用。

即使我可以阅读以找到说明,也可以继续阅读,但我自己却找不到。

1 个答案:

答案 0 :(得分:0)

您的代码正在执行的操作是选择尚未处理的前100行,更新这些行以将其标记为“已处理”,然后将刚刚更新的行中的ids插入到临时表,大概用于处理。

这意味着发生的第一件事是将这些行标记为已处理,这样就不会出现其他作业,并且在仍在处理它们时选择它们进行处理。