Имя: Пароль:
1C
1С v8
Быстрая модификация большого регистра сведений
0 Вик72
 
14.11.18
15:46
Есть большой регистр сведений. У него два измерения - "Документ" и "ИДСтроки". ИДСтроки все уникальные. Для одного документа может быть, например, 50000 строк. Задача - для некоторых ИДСтроки нужно будет перезаписывать значения реквизитов. Сложность в том, что количество изменяемых строк бывает разное - как 10 строк из 50000, так и 1000, или даже все 50000 строк. Если нужно обработать много строк, то  алгоритм очевиден: делаем читаем НаборЗаписей с отбором Документ, получаем эти 50000 записей, перебираем их в цикле и записываем набор:

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


Если обрабатываемых строк мало, то читаем и записываем построчно.

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


Проблема возникает, когда нужно модифицировать 100 строк, потому что если читать и записывать набор записей построчно по ИдСтроки (даже в транзакции), скорость работы получается медленнее, чем если прочитать и записать все 50000 строк через один набор записей. Можно ли как-нибудь сделать этот процесс быстрее? Если было бы можно читать набор записей через отбор "ВСписке", это бы решило проблему:

Для каждого ИдСтроки Из МассивСтрок Цикл
НаборЗаписей.Отбор.ИдентификаторСтроки.ВидСравнения = ВидСравнения.ВСписке;
НаборЗаписей.Отбор.ИдентификаторСтроки.Значение = СписокИдСтроки;
НаборЗаписей.Отбор.ИдентификаторСтроки.Использование = Истина;
НаборЗаписей.Прочитать();
Для каждого ЗаписьРегистра Из НаборЗаписей Цикл
ЗаписьРегистра.Реквизит = НовыйРеквизит;
КонецЦикла;
НаборЗаписей.Записать();

Но, к сожалению, "ВидСравнения" для набора записей может быть только "Равно", поэтому ради записи 100 строк из 50000, приходится читать и записывать все 50000 строк, получается, ресурсы на 49900 строк тратятся впустую. Не могу придумать, как это сделать быстрее (прямая запись в SQL не подходит)
1 Волшебник
 
14.11.18
15:48
Пользуйся МенеджерЗаписи и убери транзакцию
2 Михаил Козлов
 
14.11.18
16:05
Можно попробовать "разбить" массив ИД-ов на группы по наборам (документов).
Если в группе мало записей - через менеджер записи, если много - через набор записей (например все ИД-ы из одного набора)..
3 H A D G E H O G s
 
14.11.18
16:08
(0) МенеджерЗаписи - это НаборЗаписей с 1 Записью и ОбменДанными=Истина.
4 H A D G E H O G s
 
14.11.18
16:08
(0) Никак.
5 H A D G E H O G s
 
14.11.18
16:09
Есть извращенный вариант, но вам он не подойдет
6 Tonik992
 
14.11.18
16:14
(3) И с двумя запросами в СУБД, на Удаление и на Вставку
7 H A D G E H O G s
 
14.11.18
16:17
(6) НаборЗаписей в режиме ОбменДанными делает только вставку. Но это автору не сильно поможет
8 NuclearWinter
 
14.11.18
16:25
H A D G E H O G s
>>> и ОбменДанными=Истина

Без данного свойства.
9 Вик72
 
14.11.18
16:40
(1) Благодарю, через МенеджерЗаписи работает в 20-30 раз быстрее. Но транзакцию убирать не стоит - вне транзакции работает в 2-3 раза медленнее, чем в ней!
Я ранее как-то не углублялся в вопрос, и меня ввела в заблуждение глупая статья на "ИТС":

"Назначение и особенности использования менеджера записи регистра сведений"

<...> С точки зрения производительности использование наборов записей будет максимально эффективным. Использование менеджера записей в некоторых случаях будет столь же эффективным, а в некоторых менее, так как будут выполняться лишние действия.
https://its.1c.ru/db/metod8dev/content/2722/hdoc
10 ptiz
 
14.11.18
16:43
(9) Менеджер записи абсолютно идентичен Набору из одной записи. Видимо, код модуля мешал (срабатывавший при ОбменЗаписи <> Истина).
11 Вик72
 
14.11.18
16:48
(10) Получается, не идентичен) Даже если он близок с точки зрения запроса к БД, могут быть накладные расходы от сервера 1С. А модуль набора записей абсолютно пуст, и подписок никаких нет.
12 Tonik992
 
14.11.18
17:18
(11) Проверил. Однако, в некоторых случаях даже быстрее.
13 Вик72
 
14.11.18
17:23
(12) На моих данных разница реально в десятки раз!
14 Bober
 
14.11.18
19:11
(13) интересно.