SQL Server更新 - 有没有办法通过跳过行来避免重复?

时间:2013-04-15 14:06:42

标签: sql-server sql-update constraints

我试图将数据从一个语言环境移动到另一个语言环境,如果第二个语言环境中尚不存在。我正在使用的声明需要20个小时才能执行,所以我很感激有关如何更有效地执行此操作的任何想法。

update table 
set localeid = 3 
where localeid = 1 
  and not exists 
          (select id from table as b where localeid = 3 and id = b.id)

我想知道是否有某种方法可以使用约束并让SQL跳过违反约束的行而不是整个更新失败。在这种情况下,约束是使id,localeid主键。

可以这样做吗?

P.S。优化此查询所需的索引已经到位,但由于此数据库的大小已超过7000万条,因此仍需要永久保存。

3 个答案:

答案 0 :(得分:0)

这样的事情怎么样?这可能会更好,因为它消除了子查询。

update a
set localeid = 3
from table a
left join table b on b.id = a.id and b.localeid = 3
where a.localeid = 1
and b.id is null

答案 1 :(得分:0)

我通常把它写成:

update a
   set localeid = 3
from
   table a
     left join
   table b
     on
        a.id = b.id and
        b.localeid = 3
where
    a.localeid = 1 and
    b.id is null

但是否会改善表现,我不知道

答案 2 :(得分:0)

根据Damien和Becuzz的建议,消除子查询可能会有所帮助......如果没有,你可以尝试以下方法。 EXISTS总是比NOT EXISTS更快......所以首先要获得你想要更新的ID,而不是排除你不想想要的那些。在温度表上运行以下命令创建索引。即使有7000万行,也不应该花太长时间。

create table #IdsToUpdate (Id INT);

insert  #IdsToUpdate (Id)
select  id 
from    table 
group by id
having  max(case when localeid = 3 then 1 else 0 end) = 0;

create index in1 on #IdsToUpdate(Id);

然后根据临时表尝试实际更新:

update  t
set     t.localeid = 3
from    table t
where   exists (
            select  top 1 1
            from    #IdsToUpdate i
            where   i.Id = t.id);

另外,如果可能......您可以将数据库置于简单的恢复模式吗?记录的更新需要更长的时间。