0

毎日、テーブル内の約 800 万行 (場合によってはそれ以上) を削除する必要があるクリーンアップ プロセスがあります。このプロセスは C# で記述されており、SMO を使用してテーブル インデックスのスキーマをクエリし、500K 行のバッチで削除する sproc を実行する前にそれらを無効にします。

私の問題は、操作全体がトランザクション内にあることです。sproc は、TransactionScopeOption.Suppress で構成された TransactionScope 内で実行されます (これは、それぞれが新しい TransactionScope を開始する他のものに沿って実行されます)。これは、トランザクションを許可しないと考えられ、sproc 内に明示的なコミット ポイントがあります。

プロセスの C# 部分は次のように要約できます。

        try {
            DisableIndexes(table);
            CleanTable(table);
        }
        finally {
            RebuildIndexes(table);
        }

そして、sprocには基本的にループが含まれています:

DECLARE @rowCount bigint = 1

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

WHILE @rowCount <> 0 BEGIN
    DELETE TOP (@rowsPerBatch) Table 
    WHERE
        ID <= @maxID 

    SET @rowCount = @@rowcount
END

昨夜、このプロセスは開始から 30 分後にタイムアウトになり、ロールバックに 30 分かかり、さらに 30 分はインデックスの再構築にかかりました...ゼロワークにはダウンタイムが長すぎます...=(

更新:小さなサンプル データベースで (そして短いタイムアウトで) プロセスを実行しましたが、思ったほどではありませんでした。明らかに、プロセスは行を正しく削除し、私が望むように進行しています。それでも、ログは消費されています。私は SIMPLE データベース モードにいるので、この場合、ログは大きくなりませんか? または、削除 sproc が非常に「高速」であるため、実際に行を削除するプロセスに、ログをクリーンに保つために必要な時間を与えていませんか?

4

2 に答える 2

1

状況によっては、分割テーブルの代わりに分割ビューを使用できる場合があります。何かのようなもの:

create table A
(
    X int,
    Y int,
    Z varchar(300),
    primary key (X,Y),
    check (X = 1)
)

create table B
(
    X int,
    Y int,
    Z varchar(300),
    primary key (X,Y),
    check (X = 2)
)

create table C
(
    X int,
    Y int,
    Z varchar(300),
    primary key (X,Y),
    check (X = 3)
)

go

create view ABC
as
select * from A
union all
select * from B
union all
select * from C

go

insert abc (x,y,z)
values (1,4,'test')

insert abc (x,y,z)
values (2,99,'test'), (3,123,'test')

insert abc (x,y,z)
values (3,15125,'test')

select * from abc

truncate table c

select * from abc
于 2012-04-11T17:41:15.917 に答える
0

私があなたの問題を正しく理解していれば、あなたが望むのは自動スライディング ウィンドウとパーティション分割されたテーブルです。

于 2012-04-11T06:36:36.960 に答える