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