Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Актуализирайте всички дублиращи се записи в таблицата в SQL Server освен един

Можете да разрешите този проблем без присъединяване, което означава, че трябва да има по-добра производителност. Идеята е да групирате данните по вашия 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

Това ще помогне да продължите да заключвате, ако други едновременни сесии се опитват да получат достъп до тази таблица.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. как да конфигурирате максимално използване на паметта на SQL Server

  2. Примери за преобразуване на „дата“ в „datetime2“ в SQL Server (T-SQL)

  3. Вмъкнете varbinary данни в базата данни на SQL Server

  4. Създаване на заглавка на колона Gridview чрез зареждане на данни от база данни

  5. По-висок резултат от заявката с ключовата дума DISTINCT?