Удаление большого количества записей

1. Briolin1C 23.11.23 13:15 Сейчас в теме
Доброго времени суток.
Есть независимый непериодический РС с более чем тысячами строк.
Нужно удалить записи на определенную дату.

Схема такая всего этого действия: "в лоб" получаю запросом строки из РС которые должны быть удалены, обхожу выборку и удаляю строки в РС через МенеджерЗаписи.
Проблема в том что на этапе получения данных запросом, иногда база висит, а когда доходит до удаления, то после несколько тысяч удаленных строк, сеанс завершается с ошибкой(

Решил попробовать получить записи запросом постепенно, используя "выбрать первые".
Схема такая:
1. Пишу текст запроса использую выбрать первые. Размер определяю 500. Использую левое соединение с созданной ТЗ для исключения уже полученных записей.
2. Открываю цикл "пока истина"
3. Устанавливаю параметры
4. В обходе выборки запроса, заполняю ТЗ выборкой, после заполняю значения измерений,ресурсов,реквизитов РС, читаю, удаляю

Но ошибка никуда не делась, код выполняется долго и база "висит".
Может где-то ошибка в логике получения данных и обработкой порциями?
Пример кода:

        
	
МенеджерЗаписи = РегистрыСведений.СведенияОТоварах.СоздатьМенеджерЗаписи();

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ТЗ.ИД КАК ИД,
	|	ТЗ.КодТовара КАК КодТовара
	|ПОМЕСТИТЬ ВТ_ТЗ
	|ИЗ
	|	&ТЗ КАК ВТ_ТЗ
	|
	|ИНДЕКСИРОВАТЬ ПО
	|	ИД,
	|	КодТовара
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ ПЕРВЫЕ 500
	|	СведенияОТоварах.ИД КАК ИД,
        |	СведенияОТоварах.КодТовара КАК КодТовара,
        |	СведенияОТоварах.Категория КАК Категория,
        |	СведенияОТоварах.ДатаСведений,
................остальные 15 полей................................................
	|ИЗ
	|	РегистрСведений.СведенияОТоварах КАК СведенияОТоварах
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ТЗ КАК ВТ_ТЗ
	|		ПО СведенияОТоварах.ИД = ВТ_ТЗ.ИД
	|			И СведенияОТоварах.КодТовара = ВТ_ТЗ.КодТовара
	|ГДЕ
	|   ВТ_ТЗ.ИД ЕСТЬ NULL
	|	И СведенияОТоварах.Организация = &Организация
	|	И СведенияОТоварах.ДатаСведений >= &ДатаНачала
	|	И СведенияОТоварах.ДатаСведений <= &ДатаОкончания";  
	
	Пока Истина Цикл 
		Запрос.УстановитьПараметр("ТЗ",      ВТ_ТЗ);	
		Запрос.УстановитьПараметр("Организация",    Организация);
		Запрос.УстановитьПараметр("ДатаНачала",    ДатаНачала);
		Запрос.УстановитьПараметр("ДатаОкончания",  ДатаОкончания);
		
		РезультатЗапроса = Запрос.Выполнить();
		Если РезультатЗапроса.Пустой() Тогда
			Прервать;
		КонецЕсли;

		Выборка = РезультатЗапроса.Выбрать();

		Пока Выборка.Следующий() Цикл
			
			НоваяСтрока = ВТ_ТЗ.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);	               
                        ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
			МенеджерЗаписи.Прочитать();
			МенеджерЗаписи.Удалить();
						
		КонецЦикла;
		
				
	КонецЦикла;

Показать
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. RustamZz 23.11.23 13:21 Сейчас в теме
4. glek 119 23.11.23 13:36 Сейчас в теме
(1) если тех, которые требуется удалить больше, чем тех, которые надо оставить, то выбрать запросом записи из РС, которые надо оставить, создать набор записей, загрузить туда результат запроса и записать с замещением.
Как вариант (уже поэтапный) - сделать копию РС, перенести туда все записи из оригинального, оригинальный почистить и потом переносить из клона (можно поэтапно) правильные записи. В конце клон удалить (я бы, кстати, не удалял - пить/есть не просит, а вдруг что надо будет выдернуть).
6. Briolin1C 23.11.23 13:51 Сейчас в теме
(4) Не хотелось бы создавать копии объектов. Может всё таки можно оптимизировать логику порционной выборки?
8. Sashares 34 23.11.23 13:54 Сейчас в теме
(6)Зачем вы вообще какую то проверку с таблицей делаете?
Вы удаляете записи из регистра, все, они удалены. Зачем для этого нужна дополнительная таблица для проверки этого?
9. Briolin1C 23.11.23 13:58 Сейчас в теме
(8) дополнительная таблица нужна, что бы отсечь уже выбранные записи, т.е. выбираю данные первые 500, и сдвинуть выборку на следующие 500 записей
10. Sashares 34 23.11.23 13:59 Сейчас в теме
(9)Вы удаляете записи из регистра.
Нет этих первых 150 записи после удаления. УДАЛЕНЫ ОНИ.
Первыми 150 будут уже другие записи.

Следующий запрос новой порции записей выполняется после удаления предыдущей порции.
Поэтому достаточно выбирать просто первые ххх записей с нужным отбором и удалять их.
Никакая таблица для доп. проверки не нужна.
14. Briolin1C 23.11.23 14:37 Сейчас в теме
17. Briolin1C 24.11.23 08:10 Сейчас в теме
3. soft_wind 23.11.23 13:33 Сейчас в теме
(1)
РС, читаю, удаляю

используйте набор записей,
1.установили Отбо
2.Записали

ЧИТАТЬ НЕ НАДО
user2014960; +1 Ответить
5. Briolin1C 23.11.23 13:37 Сейчас в теме
(3) РС независимый, непериодический. Отбор в наборе записей можно устанавливать только измерениям, а ДатаСведений по которой я устанавливаю отбор в запросе, это реквизит (((

Т.е это лишнее? "МенеджерЗаписи.Прочитать();"
7. Sashares 34 23.11.23 13:52 Сейчас в теме
Менеджер записи внутри цикла объявляйте
МенеджерЗаписи = РегистрыСведений.СведенияОТоварах.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
МенеджерЗаписи.Удалить();
user2014960; +1 Ответить
15. Briolin1C 23.11.23 14:37 Сейчас в теме
11. soft_wind 23.11.23 14:04 Сейчас в теме
(5) у вас РС без измерений?
12. Sashares 34 23.11.23 14:08 Сейчас в теме
(11)Тогда была бы 1 запись))
user2014960; +1 Ответить
13. Briolin1C 23.11.23 14:36 Сейчас в теме
16. soft_wind 23.11.23 14:53 Сейчас в теме
(13) понятно,

попробовали как сказали в (7) сделать?
только создание МЗ до цикла (1 раз сделайте)
18. Briolin1C 24.11.23 08:11 Сейчас в теме
добавил до цикла создание менеджера записи.
Убрал проверку на доп.таблицу.
Ограничил выборку 100 записями.
При удалении больше 50 тыс записей РС, платформа выдает ошибку "Невосстановимая ошибка
Ошибка при выполнении запроса POST к ресурсу /e1cib/logForm:"
21. Sashares 34 24.11.23 11:57 Сейчас в теме
(18)Я бы предложил добавить установку блокировки данных регистра по результату запроса и вынести цикл с удалением записей в отдельную процедуру.
19. soft_wind 24.11.23 10:01 Сейчас в теме
(18) а удаление 100 записей проходит нормально?
попробуйте удалять по 1000

немного допишите программу и запустите удаление циклами по 1000 записей
с использованием ОбработчикаОжиданий. (например с интервалом 1 мин)
20. SlavaKron 24.11.23 11:20 Сейчас в теме
Удалять порции в транзакции еще не предлагали?
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот