Il s'agit d'une version modifiée de la réponse de @Aleksandr Fedorenko qui ajoute une clause WHERE :
UPDATE x
SET x.CODE_DEST = x.New_CODE_DEST
FROM (
SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST
FROM DESTINATAIRE_TEMP
) x
WHERE x.CODE_DEST <> x.New_CODE_DEST AND x.CODE_DEST IS NOT NULL
En ajoutant une clause WHERE, j'ai constaté que les performances s'amélioraient massivement pour les mises à jour suivantes. Sql Server semble mettre à jour la ligne même si la valeur existe déjà et cela prend du temps, donc l'ajout de la clause where lui permet de sauter les lignes où la valeur n'a pas changé. Je dois dire que j'ai été étonné de la rapidité avec laquelle il a pu exécuter ma requête.
Avertissement : je ne suis pas un expert en bases de données, et j'utilise PARTITION BY pour ma clause, donc il se peut que les résultats ne soient pas exactement les mêmes pour cette requête. Pour moi, la colonne en question est la commande payée d'un client, donc la valeur ne change généralement pas une fois qu'elle est définie.
Assurez-vous également que vous disposez d'index, en particulier si vous avez une clause WHERE dans l'instruction SELECT. Un index filtré a bien fonctionné pour moi, car je filtrait sur la base des statuts de paiement.
Ma requête utilise PARTITION by
UPDATE UpdateTarget
SET PaidOrderIndex = New_PaidOrderIndex
FROM
(
SELECT PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex
FROM [Order]
WHERE PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null
) AS UpdateTarget
WHERE UpdateTarget.PaidOrderIndex <> UpdateTarget.New_PaidOrderIndex AND UpdateTarget.PaidOrderIndex IS NOT NULL
-- test to 'break' some of the rows, and then run the UPDATE again
update [order] set PaidOrderIndex = 2 where PaidOrderIndex=3
La partie "IS NOT NULL" n'est pas nécessaire si la colonne n'est pas annulable.
Quand je dis que l'augmentation des performances a été massive, je veux dire qu'elle a été pratiquement instantanée lors de la mise à jour d'un petit nombre de lignes. Avec les bons index, j'ai pu réaliser une mise à jour qui prenait le même temps que la requête "interne" :
SELECT PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex
FROM [Order]
WHERE PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null