Как выполнить sproc без транзакции?

У меня есть процесс очистки, который должен удалять около 8 миллионов строк в таблице каждый день (иногда больше). Этот процесс написан на C# и использует SMO для запроса схемы для индексов таблиц, отключая их перед выполнением sproc, который удаляет пакетами по 500 тыс. Строк.

Моя проблема в том, что вся операция живет внутри транзакции. Sproc выполняется внутри TransactionScope, который сконфигурирован с TransactionScopeOption.Suppress (это выполняется вместе с другими вещами, каждый из которых запускает новый 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

Прошлой ночью этот процесс отключился через полчаса после его запуска, потребовалось полчаса для отката и еще полчаса для перестроения индекса... слишком много времени для нулевой работы...=(

Обновление: я запустил процесс для небольшой базы данных (и с небольшим таймаутом), и это не так, как я думал. Очевидно, процесс правильно удаляет строки и делает успехи, как я хочу. Тем не менее, журнал становится потребляемым. Поскольку я нахожусь в режиме ПРОСТОЙ базы данных, разве журнал не должен расти в этом случае? Или процесс удаления настолько быстр, что я не даю процессу, который фактически удаляет строки, время, необходимое для поддержания журнала в чистоте?

2 ответа

В зависимости от ваших обстоятельств вы можете использовать многораздельные представления вместо многораздельных таблиц. Что-то вроде:

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

Если я правильно понимаю вашу проблему, вам нужны автоматическое раздвижное окно и разделенные таблицы.

Другие вопросы по тегам