通常のテーブルから台帳テーブルにデータを移行する

適用対象: SQL Server 2022 (16.x) Azure SQL データベース Azure SQL Managed Instance

通常のテーブルを台帳テーブルに変換することはできませんが、既存の通常のテーブルから台帳テーブルにデータを移行してから、元のテーブルを台帳テーブルに置き換えることはできます。

データベース台帳の検証を実行する場合、そのプロセスでは各トランザクション内のすべての操作を順序付けする必要があります。 SELECT INTO または BULK INSERT ステートメントを使って通常のテーブルから台帳テーブルに数十億の行をコピーする場合、すべてが 1 つのトランザクションで実行されます。 つまり、大量のデータを完全に並べ替える必要があり、それは 1 つのスレッドで行われます。 この並べ替え操作の完了には長い時間がかかります。

通常のテーブルを台帳テーブルに変換するには、sys.sp_copy_data_in_batches ストアド プロシージャを使用することをお勧めします。 これにより、コピー操作は、トランザクションごとに 10 - 100K 行のバッチで分割されます。 その結果、データベース台帳の検証では、並列に並べ替えることができるより小さいトランザクションが使用されます。 これは、データベース台帳の検証の時間を大幅に短縮するのに役立ちます。

Note

お客様は引き続き、他のコマンド、サービス、またはツールを使って、ソース テーブルからターゲット テーブルにデータをコピーできます。 データベース台帳の検証にパフォーマンス上の影響を与えるため、大規模なトランザクションは避けてください。

この記事では、通常のテーブルを台帳テーブルに変換する方法について説明します。

前提条件

追加専用または更新可能な台帳テーブルを作成する

sys.sp_copy_data_in_batches ストアド プロシージャを使う前に、ソース テーブルと同じスキーマを使って追加専用の台帳テーブルまたは更新可能な台帳テーブルを作成する必要があります。 スキーマは、列数、列名、それらのデータ型が同じである必要があります。 TRANSACTION IDSEQUENCE NUMBERGENERATED ALWAYS の各列は、システムによって生成されるため無視されます。 テーブル間のインデックスは異なっていても問題ありませんが、ターゲット テーブルはヒープ テーブルにするか、クラスター化インデックスを持つ必要があります。 非クラスター化インデックスは後で作成する必要があります。

データベース内に次の通常の Employees テーブルがあるとします。

CREATE TABLE [dbo].[Employees](
	[EmployeeID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
	[SSN] [char](11) NOT NULL,
	[FirstName] [nvarchar](50) NOT NULL,
	[LastName] [nvarchar](50) NOT NULL,
	[Salary] [money] NOT NULL
	);

追加専用の台帳テーブルまたは更新可能な台帳テーブルテーブルを作成する最も簡単な方法は、元のテーブルをスクリプト化して LEDGER = ON 句を追加することです。 以下のスクリプトでは、Employees テーブルのスキーマに基づいて、Employees_LedgerTable という名前の新しい更新可能な台帳テーブルを作成しています。

	CREATE TABLE [dbo].[Employees_LedgerTable](
	[EmployeeID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
	[SSN] [char](11) NOT NULL,
	[FirstName] [nvarchar](50) NOT NULL,
	[LastName] [nvarchar](50) NOT NULL,
	[Salary] [money] NOT NULL
	)
    WITH 
    (
      SYSTEM_VERSIONING = ON,
      LEDGER = ON
    ); 

通常のテーブルから台帳テーブルにデータをコピーする

ストアド プロシージャ sys.sp_copy_data_in_batches では、ソース テーブルからターゲット テーブルに、それらのスキーマが同一であることを確認した後にデータがコピーされます。 このデータは、個々のトランザクションで一括コピーされます。 操作が失敗した場合、ターゲット テーブルには部分的に入力されます。 ターゲット テーブルも空である必要があります。

以下のスクリプトでは、通常の Employees テーブルから新しい更新可能な台帳テーブル Employees_LedgerTable にデータをコピーしています。

sp_copy_data_in_batches @source_table_name = N'Employees' , @target_table_name = N'Employees_LedgerTable'