とても大きなテーブルがあります。パーティション化したいのですが、できません。
データベースサイズ:1 TB、空き容量200 GB
テーブル:
パーティション分割するには、クラスター化インデックスを作成する必要があります。しかし、パーティションを作成するには、テーブルと同じサイズの空き領域が必要であり、余分な600GBはありません。
このテーブルを分割する方法はありますか?
編集1:
データを別のテーブルにコピーしてみました。
しかし、1日分のデータを別のテーブルにDELETE
(またはINSERT
)しようとすると、エラーが発生し、トランザクションログがいっぱいになり、トランザクションがロールバックされます。私のトランザクションログは約20 GBで、これ以上大きくすることはできません。
同じスキーマで、パーティション化されたオブジェクトとして新しいテーブルを作成する必要があります。オプションで、テーブルを圧縮してさらにスペースを節約できます。ページごとに平均1行しか配置していないので、どの程度のスペース節約が見られるかわかりません。新しいテーブルに数千行を入れてから圧縮して、スペースの節約がCPUオーバーヘッドに値するかどうかを確認することをお勧めします。
ドライブスペースをすべて消費することなく、またトランザクションログを肥大化させることなく、これだけのデータを移動する方法については、実行ごとに少量のデータを移動するループで実行する必要があります。処理できるウィンドウの大きさを確認するためにデータ分析を行う必要がありますが、データ量に基づいて、一度に1分ずつ行を移動する必要があると想定します。
DECLARE @processFrom as datetime
SELECT @processFrom = min(YourDateColumn)
FROM YourTable
DECLARE TABLE @Rows (...)
WHILE EXISTS (SELECT * FROM YourTable)
BEGIN
DELETE TOP (10000) FROM YourTable
OUTPUT DELETED.* INTO @Rows
WHERE YourDateColumn = @processFrom
INSERT INTO NewTable
(...)
SELECT ...
FROM @Rows
DELETE FROM @Rows
IF @@ROWCOUNT = 0
SET @processFrom = dateadd(dd, 1, @processFrom)
END
すべてが完了し、すべてのデータが新しいテーブルにあることを確認したら、古いテーブルを削除し、新しいテーブルの名前を変更して、古いテーブルの名前を付けます。この方法では何も壊れません。新しいテーブルに適用できるように、古いテーブル(存在する場合)の権限をスクリプトで削除する必要があります。
このテーブルへの外部キーを持つテーブルがある場合、これが機能する前にそれらを削除する必要があります。