这是@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,所以这个查询的结果可能不完全相同。对我来说,有问题的列是客户的付费订单,因此一旦设置该值通常不会改变。
还要确保你有索引,特别是如果你在 SELECT 语句上有 WHERE 子句。当我根据付款状态进行过滤时,过滤索引对我来说非常有用。
我使用 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”部分。
当我说性能提升巨大时,我的意思是在更新少量行时它基本上是瞬时的。使用正确的索引,我能够实现与“内部”查询本身所花费的时间相同的更新:
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