2011-02-08 4 views
0

ちょっと、ちょっと怠けています。しかし、私はあなたがすべて私を助けることができると知っている、それは素晴らしいことです。SQL Server 2005で毎日レコードを削除するには、この手順を変更する

私は毎晩実行されるテーブルのクリーンアップと削除手順を持っています。これは基本的なもので、3日以上経過したデータベース内のレコードを削除することが推奨されています。

一度に1日分のレコードを削除すると、トランザクションログの完全なエラーが発生するため、手順が毎晩失敗します。トランザクションログの設定を変更するのは苦労でしょう。

SOO、誰かが3日前からすべてを削除するようにprocを更新する方法を教えてもらえますか?意味は3日後に戻り、過去7日間、各テーブルのデータを1つずつ削除します。

私たちは24時間365日体制で監視されているエネルギー倉庫で、7日間稼働しないと誰かが気付くでしょう。

ALTER PROCEDURE [dbo].[PruneData] 
    (
    @cutoffDate DateTime 
    ) 
AS 
BEGIN 
    declare @threeDayCutoffDate DATETIME 
    set @threeDayCutoffDate = dateadd(hh, 5, DATEADD(dd, -3,dbo.DateOnly(getutcdate()))) 
    delete from LMP_DayAhead where interval < @threeDayCutoffDate 
    delete from LMP_RealTime where interval < @threeDayCutoffDate 
    delete from LMP_RealTimeIntegrated where interval < @threeDayCutoffDate 
    delete from ZonalMCP where interval < @threeDayCutoffDate 
    delete from SyncJob where synctime < @threeDayCutoffDate 
    RETURN 
END 
+0

ねえ、あなたは電力会社で働いています!クール。 –

+0

パーティショニングを見て...それは行く方法です。 –

答えて

2

ログの負荷を軽減するには、バッチで削除する必要があります。このような何か:

ALTER PROCEDURE [dbo].[PruneData] 
    (
    @cutoffDate DateTime 
    ) 
AS 
BEGIN 
    declare @threeDayCutoffDate DATETIME 
    declare @rows bigint; 
    declare @batchsize int; 
    set @threeDayCutoffDate = dateadd(hh, 5, DATEADD(dd, -3,dbo.DateOnly(getutcdate()))) 
    set @batchsize = 1000; 
    while (1=1) 
    begin 
     set @rows = 0; 
     delete top (@batchsize) from LMP_DayAhead where interval < @threeDayCutoffDate; 
     set @rows = @rows + @@ROWCOUNT; 
     delete top (@batchsize) from LMP_RealTime where interval < @threeDayCutoffDate 
     set @rows = @rows + @@ROWCOUNT; 
     delete top (@batchsize) from LMP_RealTimeIntegrated where interval < @threeDayCutoffDate 
     set @rows = @rows + @@ROWCOUNT; 
     delete top (@batchsize) from ZonalMCP where interval < @threeDayCutoffDate 
     set @rows = @rows + @@ROWCOUNT; 
     delete top (@batchsize) from SyncJob where synctime < @threeDayCutoffDate 
     set @rows = @rows + @@ROWCOUNT; 

     if 0 = @rows 
     begin 
      break; 
     end 
    end 
    RETURN 
END 

は、例えばこれを最適化する多くの方法があります。テーブルが刈り込まれたら、次のループの繰り返しでスキップします。究極の最適化は完全に削除を避けることです。代わりに、ローリングウィンドウパーティションスイッチスキームを使用してください:毎日テーブルをパーティション化し、毎日最後のパーティションを切り替えて新しいパーティションに切り替えます。これはほとんど瞬間的です。最初から最後まであなたは(秒/分)と同じ時間枠内のレコードと同じ量を削除する必要があります、あなたがバッチにそれを破った場合でもTransferring Data Efficiently by Using Partition SwitchingPartitioned Tables and Indexes in SQL Server 2005How to Implement an Automatic Sliding Window in a Partitioned Table on SQL Server 2005

+0

ああ完璧!それはチケットだ! –

+1

@Paul、@Remus - 私はバッチに分割するだけでログがいっぱいになるとは思わない。 – RichardTheKiwi

+0

@cyberwiki:トランザクションが複数のバッチに分割された場合、既存のログ再利用メソッド(バックアップログ、単純回復モデル)があれば、そのジョブを実行してログをリサイクルします。単一の長いトランザクションでは、BACKUPも単純なリカバリーもログの成長について何もできません。 –

0

を参照してください。トランザクションログでは、完全バックアップまたはログバックアップのいずれかを実行するまで、これらのすべてを記録しておく必要があります。

代わりに、トランザクションログのバックアップ頻度を増やして、ログバックアップの間に置き、削除の実行のバッチを実行します。つまり、1日あたり約100万レコードが削除されるとします。あなたが戻って7日間(オフセット3)を削除すると言いましたが、一度に3日間対処するようにシステムを設計しましょう。だから、もしあなたがこれを実行していないとしたら、それは毎日のを実行していると言われてから起こらないはずです。それに追いつくには3日かかるでしょう。

次のステップは、バッチに分割することです。

delete top(10000) from LMP_DayAhead where interval < @threeDayCutoffDate 
delete top(30000) from LMP_RealTime where interval < @threeDayCutoffDate 
delete top(20000) from LMP_RealTimeIntegrated where interval < @threeDayCutoffDate 
delete top(50000) from ZonalMCP where interval < @threeDayCutoffDate 
delete top(1000) from SyncJob where synctime < @threeDayCutoffDate 

各TOP(X)は、約1日分をカバーするように設計されています。

最終的には、午前1時20分にトランザクションログの追加バックアップをスケジュールし、このジョブを午前12時50分、午前1時10分、午前1時30分に実行します。その間にあるトランザクションログのバックアップは、次回の実行時にログをクリーンに保ちます。

これは一般的な戦略ですが、ニーズに合わせて調整することができます。

関連する問題