Это модифицированная версия ответа @Aleksandr Fedorenko с добавлением предложения 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
Добавив предложение WHERE, я обнаружил, что производительность значительно улучшилась для последующих обновлений. Кажется, что Sql Server обновляет строку, даже если значение уже существует, и для этого требуется время, поэтому добавление предложения where заставляет его просто пропускать строки, где значение не изменилось. Должен сказать, я был поражен тем, насколько быстро он мог выполнить мой запрос.
Отказ от ответственности: я не эксперт по БД, и я использую PARTITION BY для своего предложения, поэтому для этого запроса могут быть не совсем те же результаты. Для меня рассматриваемый столбец является оплаченным заказом клиента, поэтому значение обычно не меняется после его установки.
Также убедитесь, что у вас есть индексы, особенно если у вас есть предложение WHERE в инструкции SELECT. У меня отлично сработал отфильтрованный индекс, поскольку я выполнял фильтрацию по статусам платежей.
Мой запрос с использованием PARTITION по
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
Часть IS NOT NULL не требуется, если столбец не допускает значения NULL.
Когда я говорю, что прирост производительности был огромным, я имел в виду, что он был практически мгновенным при обновлении небольшого количества строк. С правильными индексами я смог добиться обновления, которое заняло то же время, что и «внутренний» запрос сам по себе:
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