【问题标题】:Massive Update with foreign key dependencies具有外键依赖项的大规模更新
【发布时间】:2017-11-07 17:53:27
【问题描述】:

我有以下疑问:

update largeTable 
set largeTable_id ='NA'; 

如果我们谈论 45m 记录表,我想知道执行此类更新的最佳做法是什么。我应该考虑级联更新吗?还是自动完成?

我以以下查询为例,分批执行更新以避免 tlog 空间问题:

DECLARE @i INT=1 

WHILE (@i <= 10) 
BEGIN
    UPDATE TOP(20000) largeTable 
    SET largeTable_id = 'NA'

    SET @i = @i + 1 
END

所以,这就是想法,任何意见或建议将不胜感激。

提前致谢:)。

添加一个新想法:

--T-SQL using the ROWCOUNT setting to control update size
SET ROWCOUNT 1000 

WHILE (1 = 1) 
BEGIN 
    BEGIN TRANSACTION 

    UPDATE tableB 
    SET TableB_TableA_id = 'NA'; 

    IF @@ROWCOUNT = 0 
    BEGIN 
        COMMIT TRANSACTION 
        BREAK 
    END 

    COMMIT TRANSACTION
END 

SET ROWCOUNT 0

主要目标是在多个批次中执行该更新以避免 tlog 数据文件中的问题,并执行级联更新而不会出现性能问题。

【问题讨论】:

  • 我认为您的示例中缺少 = 。
  • 分批执行此操作是个好主意。但是,您正在更新前 20000 行,但没有指定顺序,因此您可能会更新相同的 20,000 行 10 次。我建议在其中添加一个 where 子句。并使用 while @@ROWCOUNT > 0 代替固定数量的迭代。当然,您的 SET 中缺少等号
  • 避免不必要的更新总是一个好主意 - 所以添加“where isnull(largeTable_id, '') 'NA'” - 以防这些值确实存在。
  • 是的,很抱歉缺少=:
  • 你的例子中的外键是什么?

标签: sql-server tsql migration


【解决方案1】:
DECLARE @AffectedRows INT, @BatchSize INT;

SET @BatchSize = 5000;    
SET @AffectedRows = @BatchSize;

WHILE (@Rows = @BatchSize)
BEGIN
  UPDATE TOP (@BatchSize) tableB 
  SET   TableB_TableA_id='NA'
  WHERE TableB_TableA_id <> 'NA';

  SET @AffectedRows = @@ROWCOUNT;
END;

【讨论】:

  • 你好,Mihai,为什么这部分是 FROM tableB B ?
  • 是另一种形式的 UPDATE 语句。我让它变得更简单了。请重新检查...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
相关资源
最近更新 更多