1С. Удаление записей регистра сведений

Необходимо произвести удаление записей регистра сведений. В таких случаях часто создается и записывается пустой набор записей. Но это не оптимальный вариант…

Разберем примеры удаления записей из регистра сведений «Данные для обработки» некой конфигурации, регистр имеет одно измерение «Номенклатура«, тип Справочник.Номенклатура.

Создание и запись пустого набора

Заголовок говорит сам за себя:

&НаСервере
Процедура УдалитьЗаписиНаСервере()
	
	НаборЗаписей = РегистрыСведений.ДанныеДляОбработки.СоздатьНаборЗаписей();
	НаборЗаписей.Записать(Истина);
	
КонецПроцедуры

При большом количестве записей будет расходоваться оперативная память и образуется очередь на диск.

Чтение и запись порциями

Просто берем из регистра записи порциями и обрабатываем, пока записи не кончатся:

&НаСервере
Процедура УдалитьЗаписиНаСервере()
	
	Продолжать = Истина;
	
	Пока Продолжать Цикл 
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 1000
		|	ДанныеДляОбработки.Номенклатура
		|ИЗ
		|	РегистрСведений.ДанныеДляОбработки КАК ДанныеДляОбработки";
		
		Продолжать = Не Запрос.Выполнить().Пустой();
		
		Выборка = Запрос.Выполнить().Выбрать();
				
		Пока Выборка.Следующий() Цикл 
			
			НаборЗаписей = РегистрыСведений.ДанныеДляОбработки.СоздатьНаборЗаписей();
			
			НаборЗаписей.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
			
			НаборЗаписей.Записать(Истина);
			
		КонецЦикла;
				
	КонецЦикла;

КонецПроцедуры

При таком варианте расходование оперативной памяти будет более рациональным, но будет много операций записи

Чтение и запись порциями в транзакциях

По сути берется предыдущий вариант, но цикл обхода записей заключаем в транзакцию:

&НаСервере
Процедура УдалитьЗаписиНаСервере()

	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = "" + ТекущаяДата() + " Начало";
	Сообщение.Сообщить();
	
	Продолжать = Истина;
	
	Пока Продолжать Цикл 
		
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 1000
		|	ДанныеДляОбработки.Номенклатура
		|ИЗ
		|	РегистрСведений.ДанныеДляОбработки КАК ДанныеДляОбработки";
		
		Продолжать = Не Запрос.Выполнить().Пустой();
		
		Выборка = Запрос.Выполнить().Выбрать();
		
		НачатьТранзакцию();
		
		Пока Выборка.Следующий() Цикл 
			
			НаборЗаписей = РегистрыСведений.ДанныеДляОбработки.СоздатьНаборЗаписей();
			
			НаборЗаписей.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
			
			НаборЗаписей.Записать(Истина);
			
		КонецЦикла;
		
		ЗафиксироватьТранзакцию();
		
	КонецЦикла;

	Сообщение = Новый СообщениеПользователю;
	Сообщение.Текст = "" + ТекущаяДата() + " Завершение";
	Сообщение.Сообщить();
	
КонецПроцедуры

Таким образом мы уменьшим количество записей в БД.

Сравнение

Сравним скорость удаления 1 000 000 записей порциями по 1 000 записей с использованием транзакций и без них. Используется файловая ИБ расположенная на жестком диске SATA 3(Специально используется жестки диск, а не SSD для более выраженного различия).

Удаление порциями: 25 минут 12 секунд
Удаление порциями с транзакциями: 15 минут 43 секунды

Понравилась статья? Поделиться с друзьями:
Комментарии: 4
  1. Вера

    Спасибо вам огромное! Именно благодаря вашей статье я смогла написать обработку по очистке регистра сведений «Графики Работ по Видам Времени», удалить в одной транзакции не получалось появлялась ошибка «Нехватка памяти».

    1. Guesto (автор)

      Рад, что пригодилось!

  2. Алекей

    Спасибо за полезную информацию!

    1. Guesto (автор)

      Алексей, пожалуйста!

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: