Ceci est une version modifiée de la réponse de @Aleksandr Fedorenko ajoutant 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 trouvé que les performances se sont considérablement améliorées pour les mises à jour ultérieures. Sql Server semble mettre à jour la ligne même si la valeur existe déjà et que cela prend du temps, donc l'ajout de la clause where fait simplement sauter les lignes où la valeur n'a pas changé. Je dois dire que j'ai été étonné de la vitesse à laquelle il pouvait exécuter ma requête.
Clause de non-responsabilité: je ne suis pas un expert de la base de données et j'utilise PARTITION BY pour ma clause, il se peut donc 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 avez des index, en particulier si vous avez une clause WHERE sur l'instruction SELECT. Un index filtré fonctionnait très bien pour moi car je filtrais en fonction des statuts de paiement.
Ma requête utilisant PARTITION par
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 requise si la colonne n'est pas NULL.
Quand je dis que l'augmentation des performances était massive, je veux dire qu'elle était essentiellement 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 a pris le même temps que la requête `` interne '' elle-même:
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
UPDATE myCol = myCol+1 FROM MyTable WHERE ID=@MyID