sql >> データベース >  >> RDS >> Sqlserver

1億2000万件のレコードを更新する最速の方法

    1億2000万レコードのテーブルを更新する唯一の正しい方法は、SELECTを使用することです。 を入力するステートメント テーブル。これを行うときは注意する必要があります。以下の手順。

    シンプルなケース

    クラスタ化インデックスがないテーブルの場合、同時DMLがない時間中:

    • SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
    • 新しいテーブルにインデックスや制約などを再作成します
    • ALTER SCHEMA...TRANSFERを使用して新旧を切り替えます。
    • 古いテーブルを削除する

    クローンスキーマを作成できない場合は、同じスキーマ内の別のテーブル名で作成できます。切り替え後、すべての制約とトリガー(該当する場合)の名前を変更することを忘れないでください。

    単純ではないケース

    まず、BaseTableを再作成します clone.BaseTableなど、別のスキーマで同じ名前を使用する 。別のスキーマを使用すると、後で名前変更プロセスが簡素化されます。

    • クラスター化されたインデックスを含める 、 該当する場合。主キーと一意の制約がクラスター化される場合がありますが、必ずしもクラスター化されるとは限りません。
    • ID列と計算列を含める 、該当する場合。
    • 新しいINT列を含める 、どこに属していても。
    • 含めないでください 次のいずれか:
      • トリガー
      • 外部キーの制約
      • 非クラスター化インデックス/主キー/一意の制約
      • 制約またはデフォルトの制約を確認します。デフォルトではあまり違いはありませんが、最小限に抑えるようにしています。

    次に、1000行の挿入をテストします:

    -- assuming an IDENTITY column in BaseTable
    SET IDENTITY_INSERT clone.BaseTable ON
    GO
    INSERT clone.BaseTable WITH (TABLOCK) (Col1, Col2, Col3)
    SELECT TOP 1000 Col1, Col2, Col3 = -1
    FROM dbo.BaseTable
    GO
    SET IDENTITY_INSERT clone.BaseTable OFF
    

    結果を調べます。すべてが順番に表示される場合:

    • クローンテーブルを切り捨てる
    • データベースが一括ログまたは単純なリカバリモデルになっていることを確認してください
    • 完全な挿入を実行します。

    これにはしばらく時間がかかりますが、更新ほど長くはありません。完了したら、クローンテーブルのデータをチェックして、すべてが正しいことを確認します。

    次に、クラスター化されていないすべての主キー/一意の制約/インデックスと外部キーの制約を(この順序で)再作成します。必要に応じて、デフォルトを再作成し、制約を確認します。すべてのトリガーを再作成します。各制約、インデックス、またはトリガーを別々のバッチで再作成します。例:

    ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
    GO
    -- next constraint/index/trigger definition here
    

    最後に、dbo.BaseTableを移動します バックアップスキーマとclone.BaseTableに dboスキーマ(またはテーブルが存在するはずの場所)に移動します。

    -- -- perform first true-up operation here, if necessary
    -- EXEC clone.BaseTable_TrueUp
    -- GO
    -- -- create a backup schema, if necessary
    -- CREATE SCHEMA backup_20100914
    -- GO
    BEGIN TRY
      BEGIN TRANSACTION
      ALTER SCHEMA backup_20100914 TRANSFER dbo.BaseTable
      -- -- perform second true-up operation here, if necessary
      -- EXEC clone.BaseTable_TrueUp
      ALTER SCHEMA dbo TRANSFER clone.BaseTable
      COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
      SELECT ERROR_MESSAGE() -- add more info here if necessary
      ROLLBACK TRANSACTION
    END CATCH
    GO
    

    ディスクスペースを解放する必要がある場合は、この時点で元のテーブルを削除できますが、しばらくの間保持するのが賢明かもしれません。

    言うまでもなく、これは理想的にはオフラインです。 手術。この操作の実行中にデータを変更する人がいる場合は、スキーマスイッチを使用して補正操作を実行する必要があります。 dbo.BaseTableでトリガーを作成することをお勧めします すべてのDMLを別のテーブルに記録します。挿入を開始する前に、このトリガーを有効にしてください。次に、スキーマ転送を実行するのと同じトランザクションで、ログテーブルを使用して補正を実行します。最初にデータのサブセットでこれをテストしてください!デルタは簡単に台無しになります。



    1. MySQLサーバー接続は暗号化されて安全ですか?

    2. freeTDSはその構成を使用していません

    3. MySQLでのTO_BASE64()関数のしくみ

    4. MacOSにXAMPPをインストールした後にMySQLサーバーに接続する方法