2012-02-13 9 views
5

私が働いている会社には、トランザクションで10秒ごとに書き込まれている巨大なログ/ジャーナルテーブルがあります。私は、古いデータの約75%がアーカイブテーブルなどに置かれる可能性があるため、このテーブルのデータを多くコピーして削除したいと思いますが、これを間違えてテーブルがロックされるとそれは災害になるでしょう。巨大な生産テーブルのデータをコピー

これまでの質問では、男がこういうことを思いついたのですが、これですべてがうまくいっていないことを知りたいのですが、ノーロックは私を安全に保ち、そうでない場合、私は何をすべきですか?

set identity_insert newtable on 
DECLARE @StartID bigint, @LastID bigint, @EndID bigint 
select @StartID = max(id)+1 
from newtable 

select @LastID = max(ID) 
from oldtable 

while @StartID < @LastID 
begin 
set @EndID = @StartID + 1000000 

insert into newtable (FIELDS,GO,HERE) 
select FIELDS,GO,HERE from oldtable (NOLOCK) 
where id BETWEEN @StartID AND @EndId 

set @StartID = @EndID + 1 
end 
set identity_insert newtable off 
go 
+1

古いレコードを削除する計画を除いて、これは素晴らしいことですか?起こっている何らかのロックなしでそれを行う方法ではありません。 – JNK

+0

ええ、私は質問を少し明確にしました。だから、通常のDB操作の方法ではなく、古いレコードを削除する最良の方法は何ですか? –

答えて

3

あなたのリストを生成する際には注意が必要ですが、バッチ削除を実行することをお勧めします。

INSERTの場合、おそらくWHILEループは必要ありません。 DELETEのために、しかし、私はこのような何か(チューンニーズへのバッチサイズ)を使用します。

WHILE 1=1 
BEGIN 
    DELETE TOP (10000) o 
    FROM OldTable o 
    INNER JOIN NewTable N 
     ON o.id = n.id 
    IF @@ROWCOUNT < 10000 BREAK; 
END 

この意志限り、削除するレコードがあるよう時点でDELETE 10Kレコード。

+0

私は大規模なテーブルで、バッチでレコードをアーカイブし、 。基本的にはあなたのコードのように見えますが、whileループの中には "begin tran"と "commit tran"があります。その後、ログをバックアップ、切り詰め、縮小しました。 –

+0

もし彼が競合を心配しているのであれば、それはテーブルをロックするのでトランザクションをしません:) – JNK

+0

ありがとうJNK、私は最初にコピーを行うと、削除を行うことをお勧めしますか?私が心配する必要があるものは何ですか?申し訳ありませんが、私はちょうどスーパー・パラノイドですが、それはうまくいくと思われます。 –

0

1つのオプションは、(あなたがすべての挿入時にGETDATE()デフォルトの表のDATETIME列を持っていると仮定して)時間でテーブルを分割することです。パーティションを使用すると、現在のパーティションに影響を与えることなく、古いパーティションでメンテナンス(ドロップ、コピーなど)を実行できます。

+1

彼は選択するのに十分な長さでテーブルをロックすることを心配していますが、パーティション方式を追加することを提案していますか?私はかなり確実にいくつかのロックを引き起こすと確信しています... – JNK

+0

@JNKはい、それは将来の予定されたダウンタイムの一部になる可能性があります –

関連する問題