Я пишу процесс, который архивирует строки из таблицы SQL Server на основе столбца datetime. Я хочу переместить все строки с датой до X, но проблема в том, что для каждой даты есть миллионы строк, поэтому выполнение BEGIN TRANSACTION ... INSERT ... DELETE ... COMMIT для каждой даты занимает слишком много времени. и блокирует базу данных для других пользователей.
Есть ли способ, которым я могу сделать это небольшими кусками? Может быть, использовать ROWCOUNT или что-то в этом роде?
Первоначально я считал что-то вроде этого:
SET ROWCOUNT 1000
DECLARE @RowsLeft DATETIME
DECLARE @ArchiveDate DATETIME
SET @ROWSLEFT = (SELECT TOP 1 dtcol FROM Events WHERE dtcol <= @ArchiveDate)
WHILE @ROWSLEFT IS NOT NULL
BEGIN
INSERT INTO EventsBackups
SELECT top 1000 * FROM Events
DELETE Events
SET @ROWSLEFT = (SELECT TOP 1 dtcol FROM Events WHERE dtcol <= @ArchiveDate)
END
Но потом я понял, что не могу гарантировать, что удаляемые строки - это те, которые я только что скопировал. Или я могу ...?
UPDATE:
Еще одним вариантом, который я рассмотрел, было добавление шага:
- ВЫБРАТЬ ТОП 1000 строк, которые соответствуют моим критериям даты, во временную таблицу
- Начать транзакцию
- Вставить из временной таблицы в архивную таблицу
- Удалить из исходной таблицы, присоединяясь к временной таблице по каждому столбцу
- Подтвердить транзакцию
- Повторяйте 1-5, пока не останется ни одной строки, соответствующей критериям даты
Кто-нибудь имеет представление о том, как расходы этой серии могут сравниться с некоторыми из других вариантов, обсуждаемых ниже?
ДЕТАЛИ: Я использую SQL 2005, так как кто-то спросил.