Можете да разрешите този проблем без присъединяване, което означава, че трябва да има по-добра производителност. Идеята е да групирате данните по вашия object_id, като броите номера на реда на всеки object_id. Това прави "разделяне по". След това можете да актуализирате, когато row_num е> 1. Това ще актуализира всички дублирани object_id с изключение на първия!
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
На тестова таблица от 82944 записа производителността беше такава (вашият пробег може да варира!):Таблица „тест“. Брой сканирания 5, логически четения 82283, физически четения 0, четения напред 0, lob логически четения 0, lob физически четения 0, lob четения напред 0. Процесорно време =141 ms, изминало време =150 ms.
Със сигурност можем да разрешим този проблем и чрез използване на вътрешно присъединяване, но като цяло това трябва да доведе до повече логични четения и по-висок процесор:
Таблица "тест". Брой сканирания 10, логически четения 83622, физически четения 0, четения напред 0, lob логически четения 0, lob физически четения 0, lob четения напред 0. Таблица „Работен файл“. Брой сканирания 0, логически четения 0, физически четения 0, изпреварващи четения 0, lob логически четения 0, lob физически четения 0, lob четения с предварително четене 0. Таблица „Работна маса“. Брой сканирания 4, логически четения 167426, физически четения 0, четения напред 0, lob логически четения 0, lob физически четения 0, lob четения напред 0. Време на процесора =342 ms, изминало време =233 ms.
За да прегледате резултатите и да актуализирате на по-малки партиди:
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
Това ще помогне да продължите да заключвате, ако други едновременни сесии се опитват да получат достъп до тази таблица.