2

10 億のレコードを含む既存の SQL サーバー テーブル (A) に datetime 列を埋め戻す必要があります。主キー(ID)でターゲットテーブル(A)を親テーブル(B)と内部結合し、日付を取得します。残念ながら、更新が非常に遅くなる原因となっている日付列にインデックスがありません。オンライン インデックスの作成が tlog 全体 (最大 150 GB) を使い果たし、オフライン インデックス ビルドが範囲外であるため、Date 列 (ID を含む) にインデックスを作成できません。

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;

バックフィルをより迅速または効率的な方法で実行するための専門家の提案。

ありがとう

4

3 に答える 3

1

チャンク更新の場合のように聞こえます。ちなみに、最近、このトピックに関する非常に網羅的な投稿が書かれています ( http://www.sqlperformance.com/2013/03/io-subsystem/chunk-deletes )。ログ管理の問題を扱います。

基本的に、実行する更新は、ログをあまり使用しない範囲でできるだけ大きなバッチに分割する必要があります。A で分割する (A.ID の範囲を更新する) か、b で分割する (B でインデックス付けされたデータ範囲 (クラスター化インデックスやその他のインデックスなど) に従って B からデータをプルする) のいずれかを実行できます。

を使用して行の範囲を選択しますWHERE ID BETWEEN @a AND @b。インデックスが作成されている場合IDは、テーブル スキャンを回避し、増分データ プルを実行できます。

于 2013-03-15T22:32:39.930 に答える
0

次のコードを試してください。1回限りの内部結合が削除され、バッチごとにコミットされます。1回限りのハッシュ結合を削除しても、おそらくあまり役​​に立ちませんが、試してみる価値はあります。

また、オンラインインデックスの作成、オンラインインデックスの更新/再構築、IDのクラスターインデックスへの日付列の追加、クラスターインデックスへの[日付]の追加はできません。 。私のクエリでは、where句には[date]だけでなくIDも条件として含まれているため、IDインデックスに[date]を追加できれば、パフォーマンスが大幅に向上し、テーブルスキャンは行われません。クラスターインデックスシーク。


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 

于 2013-03-16T08:47:27.563 に答える
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
于 2013-03-17T03:16:15.060 に答える