有没有更好的方法来拆分简单更新的工作?
Is there a better way to split work for simple updates?
我正在对 table 中的一行进行 MS SQL 服务器更新,这非常简单。我正在用另外 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';
仅此而已。但我的问题是,这是一个 table 在生产中有大量记录 运行ning ,但在 运行ning 更新之前确切的数量是未知的。
有一个时间戳列。而且可能更重要的是先更新最新的。
但我的问题可能是一个更实际的问题。
最好按时间戳将其分区并手动设置为 运行,还是有更好的方法设置为 运行?我也可以按每个更新语句来分工。
或者有什么方法可以将这样的东西放入脚本本身?
我已经尝试查看查询计划,但它没有告诉我拆分它的最佳方法。
使用更新置顶
您可以使用 while 循环和 Update Top 选项将数据更新为块:
WHILE 1 = 1
BEGIN
UPDATE top (1000) tableToUpdate
SET Column1 = 'something new'
WHERE
Column1 = 'something old';
if @@ROWCOUNT < 1000 BREAK
END
当 @@ROWCOUNT
小于块大小 1000
时,这意味着所有行都已更新。
注意,根据官方文档:
The rows referenced in the TOP expression used with INSERT, UPDATE, or DELETE are not arranged in any order.
使用 TOP 和 Order BY 进行更新
如果您希望根据时间戳更新排序数据,他们在官方文档中提到:
If you must use TOP to apply updates in a meaningful chronology, you must use TOP together with ORDER BY in a subselect statement.
例如:
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
其他有用的链接
- UPDATE (Transact-SQL) - official documentation
- How can I create a loop on an UPDATE statement that works until there is no row left to update?
- Fastest way to update 120 Million records
- Updating rows in a large table in sql server
我正在对 table 中的一行进行 MS SQL 服务器更新,这非常简单。我正在用另外 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';
仅此而已。但我的问题是,这是一个 table 在生产中有大量记录 运行ning ,但在 运行ning 更新之前确切的数量是未知的。 有一个时间戳列。而且可能更重要的是先更新最新的。
但我的问题可能是一个更实际的问题。
最好按时间戳将其分区并手动设置为 运行,还是有更好的方法设置为 运行?我也可以按每个更新语句来分工。
或者有什么方法可以将这样的东西放入脚本本身?
我已经尝试查看查询计划,但它没有告诉我拆分它的最佳方法。
使用更新置顶
您可以使用 while 循环和 Update Top 选项将数据更新为块:
WHILE 1 = 1
BEGIN
UPDATE top (1000) tableToUpdate
SET Column1 = 'something new'
WHERE
Column1 = 'something old';
if @@ROWCOUNT < 1000 BREAK
END
当 @@ROWCOUNT
小于块大小 1000
时,这意味着所有行都已更新。
注意,根据官方文档:
The rows referenced in the TOP expression used with INSERT, UPDATE, or DELETE are not arranged in any order.
使用 TOP 和 Order BY 进行更新
如果您希望根据时间戳更新排序数据,他们在官方文档中提到:
If you must use TOP to apply updates in a meaningful chronology, you must use TOP together with ORDER BY in a subselect statement.
例如:
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
其他有用的链接
- UPDATE (Transact-SQL) - official documentation
- How can I create a loop on an UPDATE statement that works until there is no row left to update?
- Fastest way to update 120 Million records
- Updating rows in a large table in sql server