编辑:如果重要的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记录。
我们希望这会导致表锁定并彼此阻塞,但事实并非如此,这意味着它确实在一定程度上起作用。
即使我可以阅读以找到说明,也可以继续阅读,但我自己却找不到。
答案 0 :(得分:0)
您的代码正在执行的操作是选择尚未处理的前100行,更新这些行以将其标记为“已处理”,然后将刚刚更新的行中的ids
插入到临时表,大概用于处理。
这意味着发生的第一件事是将这些行标记为已处理,这样就不会出现其他作业,并且在仍在处理它们时选择它们进行处理。