有没有更好的方法来拆分工作以进行简单更新?

时间:2019-02-11 20:11:28

标签: sql sql-server optimization query-optimization sql-server-2014

我正在对MS SQL Server更新表中的行,这非常简单。我要用另外4件事代替大约4件事。

update Table set Column1 = 'something new' where Column1 = 'something old';
update Table set Column1 = 'something new 2' where Column1 = 'something old 2';
update Table set Column1 = 'something new 3' where Column1 = 'something old 3';
update Table set Column1 = 'something new 4' where Column1 = 'something old 4';

这就是全部。但是我的问题是,这是一个在生产环境中运行着大量记录的表,但是在运行更新之前,确切的数目是未知的。 有一个时间戳列。首先更新最新的更新可能更重要。

但是我的问题可能是一个更精确的问题。

最好按时间戳对其进行分区,然后使其手动运行,还是有更好的方法让它运行?我还可以按每个更新语句来划分工作。

还是有某种方法可以将此类内容放入脚本本身?

我尝试查看查询计划,但是并没有告诉我将其拆分的最佳方法。

1 个答案:

答案 0 :(得分:3)

使用更新顶部

您可以使用while循环和“更新顶部”选项将数据更新为大块:

WHILE 1 = 1
BEGIN
    UPDATE top (1000) tableToUpdate
    SET Column1 = 'something new'
    WHERE 
       Column1 = 'something old';

    if @@ROWCOUNT < 1000 BREAK
END

@@ROWCOUNT小于块大小的1000时,表示所有行都已更新。

请注意,根据官方文档:

  

与INSERT,UPDATE或DELETE一起使用的TOP表达式中引用的行未按任何顺序排列。

使用TOP和Order BY更新

如果您希望基于时间戳更新排序的数据,他们在官方文档中提到:

  

如果必须使用TOP来按有意义的时间顺序应用更新,则必须在子选择语句中将TOP与ORDER BY一起使用。

例如:

WHILE 1 = 1
BEGIN
    UPDATE tableToUpdate
    SET Column1 = 'something new'
    FROM (SELECT TOP 1000 IDColumn FROM tableToUpdate WHERE tableToUpdate.Column1 = 'something old' ORDER BY TimeStamp DESC) tto
    WHERE 
       tableToUpdate.ID = tto.ID;

    if @@ROWCOUNT < 1000 BREAK
END

其他有用的链接