Anda dapat memecahkan masalah ini tanpa bergabung, yang berarti harus memiliki kinerja yang lebih baik. Idenya adalah untuk mengelompokkan data berdasarkan object_id Anda, menghitung nomor baris dari setiap object_id. Inilah yang dilakukan "partisi oleh". Kemudian Anda dapat memperbarui di mana row_num> 1. Ini akan memperbarui semua objek_id yang digandakan kecuali yang pertama!
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
Pada tabel pengujian yang terdiri dari 82944 catatan, kinerjanya seperti itu (jarak tempuh Anda mungkin berbeda!):Tabel 'tes'. Hitungan pemindaian 5, pembacaan logis 82283, pembacaan fisik 0, pembacaan ke depan 0, pembacaan logika lob 0, pembacaan fisik lob 0, pembacaan depan pembacaan lob 0.CPU time =141 md, waktu berlalu =150 md.
Kami juga dapat memecahkan masalah ini dengan menggunakan gabungan dalam, namun, secara umum ini akan menghasilkan pembacaan yang lebih logis dan CPU yang lebih tinggi:
Tabel 'tes'. Hitungan pindai 10, pembacaan logis 83622, pembacaan fisik 0, pembacaan depan membaca 0, pembacaan logika lob 0, pembacaan fisik lob 0, pembacaan depan pembacaan lob 0.Tabel 'Workfile'. Hitungan pemindaian 0, pembacaan logis 0, pembacaan fisik 0, pembacaan ke depan 0, pembacaan logika lob 0, pembacaan fisik lob 0, pembacaan ke depan lob membaca 0.Tabel 'Meja Kerja'. Hitungan pemindaian 4, pembacaan logis 167426, pembacaan fisik 0, pembacaan ke depan 0, pembacaan logika lob 0, pembacaan fisik lob 0, pembacaan ke depan lob membaca waktu 0.CPU =342 md, waktu yang berlalu =233 md.
Untuk mengulang hasil dan memperbarui dalam batch yang lebih kecil:
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
Ini akan membantu tetap mengunci jika sesi bersamaan lainnya mencoba mengakses tabel ini.