如何用数百万行加速简单的 UPDATE 查询?

And*_*ndy 6 sql t-sql sql-server sql-server-2012

如何加速这个相当简单的 UPDATE 查询?已经运行了5个多小时了!

我基本上是通过加入包含旧 ID 和新 ID 的新表来替换表中的 SourceID。所有这些字段都是 VARCHAR(72) 并且必须保持这种状态。

Pub_ArticleFaculty 表有 8,354,474 行(830 万)。ArticleAuthorOldNew 有 99,326,472 行(9,930 万),只有您在下面看到的 2 个字段。

所有这些字段都有单独的非聚集索引。有没有更好的方法来编写此查询以使其运行得更快?

UPDATE PF
        SET PF.SourceId = AAON.NewSourceId
    FROM AA..Pub_ArticleFaculty PF WITH (NOLOCK)
        INNER JOIN AA2..ArticleAuthorOldNew AAON WITH (NOLOCK)  
                   ON AAON.OldFullSourceId = PF.SourceId
Run Code Online (Sandbox Code Playgroud)

Vin*_*rst 9

根据我的经验,循环更新以便每次迭代都作用于少量行是一个很好的方法。每次迭代更新的理想行数很大程度上取决于您的环境和您正在使用的表。我通常每次迭代坚持大约 1,000 - 10,000 行。

例子

SET ROWCOUNT 1000 -- Set the batch size (number of rows to affect each time through the loop).
WHILE (1=1) BEGIN

    UPDATE PF
    SET NewSourceId = 1
    FROM AA..Pub_ArticleFaculty PF WITH (NOLOCK)
            INNER JOIN AA2..ArticleAuthorOldNew AAON WITH (NOLOCK)  
                       ON AAON.OldFullSourceId = PF.SourceId
    WHERE NewSourceId IS NULL -- Only update rows that haven't yet been updated.

    -- When no rows are affected, we're done!
    IF @@ROWCOUNT = 0
        BREAK
END
SET ROWCOUNT 0 -- Reset the batch size to the default (i.e. all rows).
GO
Run Code Online (Sandbox Code Playgroud)