Я пишу процесс, который архивирует строки из таблицы 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
Но потом я понял, что не могу гарантировать, что удаляемые мной строки - это те, которые я только что скопировал. Или я могу ...?
ОБНОВЛЕНИЕ: Я рассмотрел еще один вариант - добавить шаг:
- ВЫБЕРИТЕ ТОП 1000 строк, которые соответствуют моим критериям даты, во временную таблицу
- Начать транзакцию
- Вставить из временной таблицы в архивную таблицу
- Удалить из исходной таблицы, присоединяясь к временной таблице по каждому столбцу
- Подтвердить транзакцию
- Повторяйте 1–5, пока не останется строк, соответствующих критериям даты.
Есть ли у кого-нибудь представление о том, как можно сравнить расходы на эту серию с некоторыми другими вариантами, обсуждаемыми ниже?
ПОДРОБНЕЕ: я использую SQL 2005, так как кто-то спросил.