To jest zmodyfikowana wersja odpowiedzi @Aleksandr Fedorenko dodająca klauzulę 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
Dodając klauzulę WHERE zauważyłem, że wydajność znacznie się poprawiła w przypadku kolejnych aktualizacji. Wydaje się, że serwer Sql aktualizuje wiersz, nawet jeśli wartość już istnieje i zajmuje to trochę czasu, więc dodanie klauzuli where powoduje, że po prostu pomija wiersze, w których wartość nie uległa zmianie. Muszę powiedzieć, że byłem zdumiony, jak szybko może wykonać moje zapytanie.
Zastrzeżenie: nie jestem ekspertem od DB i używam PARTITION BY dla mojej klauzuli, więc może to nie być dokładnie takie same wyniki dla tego zapytania. Dla mnie ta kolumna to płatne zamówienie klienta, więc wartość generalnie nie zmienia się po jej ustawieniu.
Upewnij się również, że masz indeksy, zwłaszcza jeśli masz klauzulę WHERE w instrukcji SELECT. Filtrowany indeks działał świetnie, ponieważ filtrowałem na podstawie statusów płatności.
Moje zapytanie przy użyciu PARTITION wg
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
Część „NIE JEST NULL” nie jest wymagana, jeśli kolumna nie dopuszcza wartości null.
Kiedy mówię, że wzrost wydajności był ogromny, mam na myśli to, że był on zasadniczo natychmiastowy podczas aktualizowania niewielkiej liczby wierszy. Dzięki odpowiednim indeksom udało mi się uzyskać aktualizację, która zajęła tyle samo czasu, co samo zapytanie „wewnętrzne”:
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