Анализ замеров показал следующие "классические" места для ускорения, и одно было нетривиальное.
К "классическим" можно отнести достаточно типовые варианты, которые типовая ЗУП нередко игнорирует, но которые сильно проявляют себя при увеличении объема данных (геометрическая прогрессия) и при использовании RLS.
- Добавление индекса в запросы
- Добавление индекса в таблицы значений для ускорения поиска в коде 1С
- "Выбрать различные". Казалось бы, неэффективный способ, но по практике есть места в запросах, которые возвращают большое количество дублей в промежуточных таблицах, и в последующих запросах возникает излишний перебор.
- "Предотбор" элементов в "где". Особенно эффективно это когда меняем отбор для "разыменования"
И был найден очень "безобидный" кусок в очередном релизе ЗУП
Общий модуль УчетСреднегоЗаработка
ИсключаемыеСтроки = Новый Массив;
Для Каждого СтрокаНачислений Из Начисления Цикл
Если ИсключаемыеСтроки.Найти(СтрокаНачислений) <> Неопределено Тогда
Продолжить;
КонецЕсли;
Для Каждого ТекущаяСтрока Из Начисления Цикл
Если СтрокаНачислений = ТекущаяСтрока Тогда
Продолжить;
КонецЕсли;
Если ИсключаемыеСтроки.Найти(ТекущаяСтрока) <> Неопределено Тогда
Продолжить;
КонецЕсли;
ЗначенияКолонокСовпадают = Истина;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Если СтрокаНачислений[ИмяКолонки] <> ТекущаяСтрока[ИмяКолонки] Тогда
ЗначенияКолонокСовпадают = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЗначенияКолонокСовпадают Тогда
Продолжить;
КонецЕсли;
Если СтрокаНачислений.Сумма = -ТекущаяСтрока.Сумма Тогда
ИсключаемыеСтроки.Добавить(СтрокаНачислений);
ИсключаемыеСтроки.Добавить(ТекущаяСтрока);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
ИсключаемыеНачисления = Начисления.Скопировать(ИсключаемыеСтроки);
Для Каждого ИсключаемаяСтрока Из ИсключаемыеСтроки Цикл
Начисления.Удалить(ИсключаемаяСтрока);
КонецЦикла;
В результате запуска профайлера выяснилось, что данный кусок кода для 6 000 сотрудников работает порядка 4 часов.
Потому что в начислений "всего" порядка 138 000 строк, и десяток колонок.
Но данный код геометрически увеличил циклы до миллиардов итераций.
Переделал этот кусок на генерацию запрос скуля.
Запрос.УстановитьПараметр("Начисления",Начисления);
Запрос.Текст="ВЫБРАТЬ Начисления.Сумма как Сумма,Начисления.Сторно как Сторно";
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Запрос.Текст=Запрос.Текст+",
|Начисления."+ИмяКолонки+" как "+ИмяКолонки;
КонецЦикла;
Запрос.Текст=Запрос.Текст+"
|Поместить ВТ_Начисления
|из &Начисления как Начисления;
|
| Выбрать
| Сумма(Начисления.Сумма) как Сумма";
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Запрос.Текст=Запрос.Текст+",
|Начисления."+ИмяКолонки+" как "+ИмяКолонки;
КонецЦикла;
Запрос.Текст=Запрос.Текст+"
|Поместить ВТ_ИсключаемыеСтроки
| из ВТ_Начисления как Начисления
| Сгруппировать по 1";
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Запрос.Текст=Запрос.Текст+",
|Начисления."+ИмяКолонки;
КонецЦикла;
Запрос.Текст=Запрос.Текст+"
| Имеющие Сумма(Начисления.Сумма)=0
| ;
|
| ВЫБРАТЬ Начисления.Сумма как Сумма,Начисления.Сторно как Сторно";
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Запрос.Текст=Запрос.Текст+",
|Начисления."+ИмяКолонки+" как "+ИмяКолонки;
КонецЦикла;
Запрос.Текст=Запрос.Текст+"
| из ВТ_Начисления как Начисления
| Левое соединение
| ВТ_ИсключаемыеСтроки как ВТ_ИсключаемыеСтроки
| по Истина ";
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Запрос.Текст=Запрос.Текст+" и
|Начисления."+ИмяКолонки+" = ВТ_ИсключаемыеСтроки."+ИмяКолонки;
КонецЦикла;
Запрос.Текст=Запрос.Текст+"
| где ВТ_ИсключаемыеСтроки."+ИмяКолонки+" есть NULL;
|
| Выбрать * из ВТ_ИсключаемыеСтроки;";
Пакет = Запрос.ВыполнитьПакет();
Начисления = Пакет[2].Выгрузить();
ИсключаемыеНачисления = Пакет[3].Выгрузить();
В итоге вся работа происходит за считанные секунды.
Проверено на релизах ЗУП КОРП 3.1.25.40 и 3.1.25.136
PS.
Вполне вероятно будет работать и на ERP 2, в связи с тем что внутри ерп модули ЗУП 3 корп