在SQL Server 2012中更新数百万条记录

aka*_*ter 1 sql t-sql sql-server-2012

我认为通过包含几个表格可以更容易解释.

表A:

UserId     StoreId
1          10
2          20
3          30
4          40
Run Code Online (Sandbox Code Playgroud)

表B:

UserId     StoreId
1          10
1          20
1          20
2          20
2          10
2          10
3          30
3          40
3          40
4          40
4          30
4          30
Run Code Online (Sandbox Code Playgroud)

我需要一个将进入表2的脚本,并更新存储以匹配该StoreId特定用户的表A. 最后,我应该看到;

表B:

UserId     StoreId
1          10
1          10
1          10
2          20
2          20
2          20
3          30
3          30
3          30
4          40
4          40
4          40
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,考虑到表B中有数亿行,而表A有大约2000万行,最简单的方法是什么?

提前致谢!

Tom*_*m H 5

最好的方法是:

ALTER TABLE Table_B
DROP COLUMN StoreId
Run Code Online (Sandbox Code Playgroud)

现在你不再存储重复数据,并且你可以得到StoreIdTable_A当你需要它.

否则它只是一个简单UPDATEJOIN:

UPDATE B
SET
    StoreId = A.StoreID
FROM
    Table_B B
INNER JOIN TABLE_A A ON A.UserId = B.UserId
Run Code Online (Sandbox Code Playgroud)

如果需要,可以将其放入执行批处理的循环中,以便减少更新的大小,使其不会泛滥事务日志.有几种方法可以做到这一点.一个例子:

DECLARE
    @batch_size INT = 10000,
    @min_user_id INT = 1,
    @max_user_id INT

SELECT @max_user_id = MAX(UserId) FROM Table_A

WHILE (@min_user_id <= @max_user_id)
BEGIN
    UPDATE B
    SET
        StoreId = A.StoreID
    FROM
        Table_B B
    INNER JOIN TABLE_A A ON A.UserId = B.UserId
    WHERE
        B.UserId BETWEEN @min_user_id AND @min_user_id + @batch_size

    SET @min_user_id = @min_user_id + @batch_size + 1
END
Run Code Online (Sandbox Code Playgroud)