Puoi risolvere questo problema senza un join, il che significa che dovrebbe avere prestazioni migliori. L'idea è di raggruppare i dati in base al tuo object_id, contando il numero di riga di ogni object_id. Questo è ciò che fa "partizione per". Quindi puoi aggiornare dove row_num è> 1. Questo aggiornerà tutti gli object_id duplicati tranne il primo!
update t set t.status_val = 'some_status'
from (
select *, row_number() over(partition by object_id order by (select null)) row_num
from foo
) t
where row_num > 1
Su una tabella di prova di 82944 record, le prestazioni erano tali (il tuo chilometraggio può variare!):Tabella 'test'. Conteggio scansioni 5, letture logiche 82283, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read-ahead lob 0. Tempo CPU =141 ms, tempo trascorso =150 ms.
Possiamo certamente risolvere questo problema anche utilizzando un inner join, tuttavia, in generale questo dovrebbe portare a letture più logiche e CPU più elevate:
Tabella 'test'. Conteggio scansioni 10, letture logiche 83622, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read-ahead lob 0.Tabella 'Workfile'. Conteggio scansioni 0, letture logiche 0, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read-ahead lob 0.Tabella 'Worktable'. Conteggio scansioni 4, letture logiche 167426, letture fisiche 0, letture read-ahead 0, letture logiche lob 0, letture fisiche lob 0, letture read-ahead lob 0. Tempo CPU =342 ms, tempo trascorso =233 ms.
Per scorrere i risultati e aggiornarli in batch più piccoli:
declare @rowcount int = 1;
declare @batch_size int = 1000;
while @rowcount > 0
begin
update top(@batch_size) t set t.status_val = 'already updated'
from (
select *, row_number() over(partition by object_id order by (select null)) row_num
from foo
where status_val <> 'already updated'
) t
where row_num > 1
set @rowcount = @@rowcount;
end
Ciò contribuirà a mantenere il blocco se altre sessioni simultanee stanno tentando di accedere a questa tabella.