1

あるロケールから別のロケールにデータを移動しようとしていますが、それが 2 番目のロケールにまだ存在していません。そのために私が使用しているステートメントは、実行に 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主キーを作成することです。

これはできますか?

ps このクエリを最適化するために必要なインデックスは配置されていますが、7,000 万を超えるエントリを持つこのデータベースのサイズが非常に大きいため、依然として時間がかかります。

4

3 に答える 3

0

Eliminating the subquery, as suggested by Damien and Becuzz, may help... If not, you can try the below. EXISTS will always be faster than NOT EXISTS... So start by getting the Ids you want to update rather than excluding the ones you don't want. Run the below up to the index creation on the temp table. Even with 70 million rows, it should not take too long.

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);

Then try the actual update based on the temp table:

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

Also, if possible... can you put your DB into simple recovery mode? Logged updates take a lot longer.

于 2013-04-15T14:55:39.643 に答える
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
于 2013-04-15T14:42:34.240 に答える