Потихоньку расскажу, как сильно ускорять тяжёлые обновления 1С. Сегодня - про ускорение отложенных обработчиков.
Чтобы понять, какие обработчики долго выполняются, достаточно обновить копию и посмотреть. В форме выполнения обработчиков прям время будет написано, в днях/часах, сколько выполнялся обработчик. А сколько ему надо было объектов промурыжить - видно в отчёте “Прогресс отложенного обновления”.
Например, у нас сильно тормозил обработчик регистра сведений “РеестрДокументов” - выполнялся больше суток. Ему надо было перезаписать 9 млн. записей (столько в базе было документов).
Ремарка по поводу того, чего он так медленно работает - распараллеливание типовое плохо работает. При обновлении можно указать количество потоков, на которое распределяются обрабатываемые данные, но предварительное расследование показало, что один обработчик всё равно выполняется в чрезвычайно малом количестве потоков. Возможно, даже в одном потоке. Это очень мало и потому очень долго.
Дальше идём в три процедуры модуля менеджера обновляемого объекта:
ПриДобавленииОбработчиковОбновления - там надо будет через расширение отключить добавление обработчика, чтобы типовое обновление его не выполняло. Там же смотрим, какой процедурой регистрируются данные к обработке (свойство ПроцедураЗаполненияДанныхОбновления, обычно там ЗарегистрироватьДанныеКОбработке). Там же смотрим, какой процедурой выполняется обработчик (свойство Процедура, обычно там ОбработатьДанныеДляПереходаНаНовуюВерсию).
Процедура регистрации (обычно ЗарегистрироватьДанныеКОбработке). В ней надо забрать запрос, который формирует данные к обработке. Обычно там всё несложно - запрос, выборка результата и его складывание в план обмена (ОбновлениеИнформационнойБазы.ОтметитьКОбработке). Нам нужен только запрос и выборка данных, в план обмена ничего писать не нужно.
Процедура выполнения обработчика (обычно ОбработатьДанныеДляПереходаНаНовуюВерсию). Там лежит код обработки. В нём много лишнего (обвес для типовых процедур обновления), но суть обычно понять несложно - читаются данные, сформированные п.2, и что-то с ними делается. Бывает, ещё один-два запроса делаются. Берём вот эту содержательную часть и забираем себе. Не забываем заменить ОбновлениеИнформационнойБазы.ОтметитьВыполнениеОбработки на обычную запись - нам не надо регистрировать обработку в плане обмена.
Дальше нужно написать обработку, которая запустит энное количество ФЗ, каждому скормит массив данных к обработке (из п.2), и ФЗ выполнит адаптированный код из п.3. Мы делали расширение, в него складывали процедуру ФЗ, на входе - массив (обычно это массив ссылок). В процедуре - код из п.3. И обработку внешнюю, в которой мы указываем количество потоков, она выполняет большой запрос из п.2, делит результат на потоки, и запускает кучу ФЗ. И всё.
Контролировать прогресс выполнения можно разными способами. Первый, который я использовал - просто выполнял запрос из п.2. Подавляющее большинство запросов в обработчиках обновления написано так, что возвращают только необработанные данные. Соответственно, их в процессе выполнения становится всё меньше. Но этот запрос может выполняться сильно долго. Потом я сделал несложный регистр сведений, и в каждое ФЗ положил пару строк записи в этот РС - после обработки каждого объекта ФЗ “отчитывалось”, и в регистре было видно общий прогресс.
При наличии нормального объёма ОЗУ запускать такие обработчики можно и в 16, и в 32, и в 48, и даже в 100 потоков (проверено). Это количество ФЗ на один обработчик. А вообще мы в это распараллеливание вывели 22 обработчика из 4 редакций.
Ускорение получается очень существенное - тот, который выполнялся сутки, стал выполняться за 4 часа.
https://t.me/ywhite