SQL Server - 需要使用十亿条记录回填表中的列

时间:2013-03-15 22:24:29

标签: sql sql-server-2008 bulkinsert

我需要将一个datetime列填入现有的sql server表(A)中,并记录十亿条记录。 我内部将目标表(A)与主键(ID)上的父表(B)连接起来,然后重新获取日期。 不幸的是,我在日期列上没有索引导致更新非常慢。 我无法在Date列(ID为include)上创建索引,因为在线索引创建占用了整个tlog(最大150gb)并且offine索引构建超出了范围。

UPDATE  A
    SET A.DATE = ZZ.DATE
FROM    A
        INNER JOIN
        (SELECT TOP 100000 A.ID,
                           B.DATE
         FROM   A WITH (NOLOCK)
                INNER JOIN
                B WITH (NOLOCK)
                -- parent table
                ON A.ID = B.ID
         WHERE  A.DATE IS NULL) AS ZZ
        ON ZZ.ID = A.ID;

任何专家建议以更快或更有效的方式进行回填。

由于

3 个答案:

答案 0 :(得分:1)

听起来像是一个分块更新的案例。顺便提一下,最近有一篇关于这个主题的文章非常详尽(http://www.sqlperformance.com/2013/03/io-subsystem/chunk-deletes)。它处理日志管理问题。

基本上,您应该将您执行的更新拆分为尽可能大的批处理,同时不会导致过多的日志使用。您可以拆分A(更新范围为A.ID)或拆分b(根据B上索引的某些数据范围从B中提取数据(例如聚集索引或任何其他索引)。

使用WHERE ID BETWEEN @a AND @b选择一系列行。如果ID被编入索引,则可以避免表扫描,并且可以执行增量数据提取。

答案 1 :(得分:0)

请尝试以下代码,删除一次性内部联接,并按批次提交。删除一次性哈希联接可能不会帮助你很多,但也许值得一试。

另外一件事是,你提到你不能做在线索引创建,你可以做一个在线索引更新/重新构建,你可以在你的集群索引上添加你的日期列ID,包括你的[date] in你集群索引。因为在我的查询中,where子句有ID作为条件,以及[date],所以,如果你可以将[date]添加到你的ID索引,它将有助于提高性能,它将没有表扫描,只有集群索引寻求。


DECLARE @ID BIGINT
SELECT @ID = MIN(ID) FROM A
WHILE @ID < IDENT_CURRENT('DBO.A')
BEGIN
    BEGIN TRAN
        UPDATE A
        SET A.DATE = B.DATE
        FROM A
        INNER JOIN B (nolock)
        ON A.ID = B.ID
        WHERE A.ID BETWEEN @ID AND @ID + 100000
        AND A.DATE IS NULL
    COMMIT TRAN
    SET @ID = @ID + 100000
END 

答案 2 :(得分:0)

UPDATE  A
    SET A.DATE = ZZ.DATE
FROM    A
        INNER JOIN
        (SELECT  A.ID, B.DATE
         FROM   A WITH (NOLOCK)
                INNER JOIN
                B WITH (NOLOCK)
                ON A.ID = B.ID

         WHERE  A.DATE IS NULL AND A.ID BETWEEN @a and @a + 100000
) AS ZZ
ON ( ZZ.ID = A.ID )
SET @X = @X + 100000
WAITFOR DELAY '00:00:05'
END