Ускоряем ЗУП 3 Корп на предприятиях с большим количеством работников

06.07.25

База данных - HighLoad оптимизация

Как только мы перешли с УПП на ЗУП 3, сразу столкнулись с огромной проблемой. Наша организация в 12 000 человек, разбив документы на 2 части по 6 000 человек, не смогла за несколько часов рассчитать зарплату, и пришлось срочно заниматься оптимизацией "на ходу". В процессе выяснилось немало ключевых мест, и в результате, как правило, небольшими "инъекциями", удалось качественно (часть участков с часов до минут, а местами и до секунд) ускорить процесс и дать возможность расчетчикам выполнять работу в сжатые сроки. В результате этого процесса получилось расширение. Которое можно просто применить на типовой ЗУП Корп. 

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Ускоряем ЗУП 3 Корп (3.1.27.193)
.cfe 911,03Kb
3 1 850 руб. Купить
Ускоряем типовой ЗУП 3 Корп (для 3.1.25.40, 3.1.25.136)
.cfe 93,46Kb
12 1 850 руб. Купить
Ускоряем ЗУП 3 Корп (3.1.27.246)
.cfe 909,14Kb ver:03.07.2024
5 1 850 руб. Купить
Ускоряем ЗУП 3 Корп (3.1.80.31)
.cfe 942,43Kb ver:15.11.2024
1 1 850 руб. Купить
Ускоряем ЗУП 3 Корп 3.1.30.81
.cfe 914,69Kb
2 1 850 руб. Купить
Ускоряем ЗУП 3 Корп на предприятиях с большим количеством работников: 3.1.30.133
.cfe 335,56Kb ver:03.07.2025
3 1 850 руб. Купить
Помошник работы с начислением в организации с большим количеством сотрудников
.epf 62,96Kb
2 1 850 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Анализ замеров показал следующие "классические" места для ускорения, и одно было нетривиальное.

К "классическим" можно отнести достаточно типовые варианты, которые типовая ЗУП нередко игнорирует, но которые сильно проявляют себя при увеличении объема данных (геометрическая прогрессия) и при использовании RLS.

  1. Добавление индекса в запросы
  2. Добавление индекса в таблицы значений для ускорения поиска в коде 1С
  3. "Выбрать различные". Казалось бы, неэффективный способ, но по практике есть места в запросах, которые возвращают большое количество дублей в промежуточных таблицах, и в последующих запросах возникает излишний перебор.
  4. "Предотбор" элементов в "где". Особенно эффективно это когда меняем отбор для  "разыменования"

И был найден очень "безобидный" кусок в очередном релизе ЗУП

Общий модуль УчетСреднегоЗаработка

	ИсключаемыеСтроки = Новый Массив;
	Для Каждого СтрокаНачислений Из Начисления Цикл 
		Если ИсключаемыеСтроки.Найти(СтрокаНачислений) <> Неопределено Тогда 
			Продолжить;
		КонецЕсли;
		Для Каждого ТекущаяСтрока Из Начисления Цикл
			Если СтрокаНачислений = ТекущаяСтрока Тогда
				Продолжить;
			КонецЕсли;
			Если ИсключаемыеСтроки.Найти(ТекущаяСтрока) <> Неопределено Тогда 
				Продолжить;
			КонецЕсли;
			ЗначенияКолонокСовпадают = Истина;
			Для Каждого ИмяКолонки Из ИменаКолонок Цикл 
				Если СтрокаНачислений[ИмяКолонки] <> ТекущаяСтрока[ИмяКолонки] Тогда
					ЗначенияКолонокСовпадают = Ложь;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если Не ЗначенияКолонокСовпадают Тогда 
				Продолжить;
			КонецЕсли;
			Если СтрокаНачислений.Сумма = -ТекущаяСтрока.Сумма Тогда 
				ИсключаемыеСтроки.Добавить(СтрокаНачислений);
				ИсключаемыеСтроки.Добавить(ТекущаяСтрока);
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	ИсключаемыеНачисления = Начисления.Скопировать(ИсключаемыеСтроки);
	Для Каждого ИсключаемаяСтрока Из ИсключаемыеСтроки Цикл 
		Начисления.Удалить(ИсключаемаяСтрока);
	КонецЦикла;
	

В результате запуска профайлера выяснилось, что данный кусок кода для 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. А это не столько место на диске, но и сокращения времени проведения документа (включая обработку связанных РС), так и сокращение времени проведения документов связанных с РС "Бухучет зарплаты сотрудников"

 

03.07.2025

Ускорено утверждение отпусков

Проверено на следующих конфигурациях и релизах:

  • Зарплата и управление персоналом, редакция 3.1, релизы 3.1.27.246, 3.1.27.193, 3.1.25.136
  • Зарплата и управление персоналом КОРП, редакция 3.1, релизы 3.1.31.67, 3.1.30.133, 3.1.30.81

Вступайте в нашу телеграмм-группу Инфостарт

ЗУП3 ускорение оптимизация

См. также

HighLoad оптимизация Программист 1C:ERP Бесплатно (free)

Использование оператора «В» для полей или данных составного типа (например, Регистратор) может приводить к неочевидным проблемам.

10.11.2025    5265    ivanov660    48    

51

HighLoad оптимизация Программист 1С:Предприятие 8 1C:ERP Бесплатно (free)

Приведем примеры использования различных в динамических списках и посмотрим, почему это плохо.

18.02.2025    8109    ivanov660    39    

61

HighLoad оптимизация Технологический журнал Системный администратор Программист Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    10536    ivanov660    13    

64

HighLoad оптимизация Программист 1С:Предприятие 8 Бесплатно (free)

Метод очень медленно работает, когда параметр приемник содержит намного меньше свойств, чем источник.

06.06.2024    16507    Evg-Lylyk    73    

46

HighLoad оптимизация Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    8109    spyke    29    

54

HighLoad оптимизация Программист 1С:Предприятие 8 Бесплатно (free)

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    11437    vasilev2015    22    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user1175436 28 10.05.23 14:45 Сейчас в теме
добрый день!

1500 сотрудников - без расширения начисление ЗП заполняется за 1 минуту , а с расширением - 1 минута 20 секунд
2. ZAOSTG 192 10.05.23 21:15 Сейчас в теме
(1)Странно очень. Профайлер есть?
3. Gesperid 2 11.05.23 11:42 Сейчас в теме
Ваш запрос делает не то, что код.
Например, в такой таблице:
ИдентификаторСтроки Сумма
84 -168
84 168
84 -190

Запрос ничего не удалит, а код удалит две первые строки.
Я бы начал с индексации таблиц.
	//+
	ИменаКолонокСтрокой = СтрСоединить(ИменаКолонок, ",");
	Начисления.Индексы.Добавить(ИменаКолонокСтрокой);

	ИсключаемыеСтрокиСоответствие = Новый Соответствие;
	//-
	
	Для Каждого СтрокаНачислений Из Начисления Цикл
		
		//+ 
		Если ИсключаемыеСтрокиСоответствие[СтрокаНачислений] <> Неопределено Тогда 
			Продолжить;
		КонецЕсли;
		
		КлючСтроки = Новый Структура(ИменаКолонокСтрокой);
		ЗаполнитьЗначенияСвойств(КлючСтроки, СтрокаНачислений);
		
		Для каждого СтрокаПотенциальная Из Начисления.НайтиСтроки(КлючСтроки) Цикл 
			Если СтрокаНачислений = СтрокаПотенциальная Тогда
				Продолжить;
			КонецЕсли;  
			
			Если ИсключаемыеСтрокиСоответствие[СтрокаПотенциальная] <> Неопределено Тогда
				Продолжить;
			КонецЕсли;
			
			//
			Если СтрокаНачислений.Сумма = -СтрокаПотенциальная.Сумма Тогда 
				ИсключаемыеСтрокиСоответствие.Вставить(СтрокаНачислений);
				ИсключаемыеСтрокиСоответствие.Вставить(СтрокаПотенциальная);
				Прервать;
			КонецЕсли;
		КонецЦикла;          
		
		Продолжить;
		//-

		Если ИсключаемыеСтроки.Найти(СтрокаНачислений) <> Неопределено Тогда 
			Продолжить;
		КонецЕсли;
		
		Для Каждого ТекущаяСтрока Из Начисления Цикл 
			Если СтрокаНачислений = ТекущаяСтрока Тогда
				Продолжить;
			КонецЕсли;  
			
			Если ИсключаемыеСтроки.Найти(ТекущаяСтрока) <> Неопределено Тогда
				Продолжить;
			КонецЕсли;  
			
			//
			ЗначенияКолонокСовпадают = Истина;
			Для Каждого ИмяКолонки Из ИменаКолонок Цикл 
				Если СтрокаНачислений[ИмяКолонки] <> ТекущаяСтрока[ИмяКолонки] Тогда
					ЗначенияКолонокСовпадают = Ложь;
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если Не ЗначенияКолонокСовпадают Тогда 
				Продолжить;
			КонецЕсли;
			
			//
			Если СтрокаНачислений.Сумма = -ТекущаяСтрока.Сумма Тогда 
				ИсключаемыеСтроки.Добавить(СтрокаНачислений);
				ИсключаемыеСтроки.Добавить(ТекущаяСтрока);
				Прервать;
			КонецЕсли;
		КонецЦикла;
		
	КонецЦикла;
	
	//+
	Для каждого КлючЗначение Из ИсключаемыеСтрокиСоответствие Цикл
		ИсключаемыеСтроки.Добавить(КлючЗначение.Ключ);
	КонецЦикла;
	//-
Показать
4. ZAOSTG 192 22.05.23 12:08 Сейчас в теме
(3)Согласен, запрос может пропустить часть данных для сворачивания
Но думаю что предложенная Вами ситуация в основном искусственная - отсторнировали и снова сделали запись
Ради таких "пропусков", делающих излишние проверки далее, жертвовать часы работы "оригинал" или "переделка" мы выбрали переделка

Ваш вариант кода тестирую на наших данных. Если поможет -огромное спасибо за совет, помещу в расширение
cleaner_it; +1 Ответить
5. Kesak 15 25.05.23 00:19 Сейчас в теме
(4) Тестирование ещё в процессе?
6. ZAOSTG 192 25.05.23 05:58 Сейчас в теме
(5)Так как код - часть, и не взлетел с ходу, потому что ИсключаемыеСтроки определяются ниже, а тут уже ищутся, не успел -завал. В рабочей уже несколько месяцев используют запрос -замечаний нет
7. artbear 1583 03.06.23 12:58 Сейчас в теме
(3) Ага, хороший вариант, но не хватает поиска в таблице по сумме, ведь она заранее известна!
плюс структуру КлючСтроки не нужно создавать каждый раз.

в итоге код становится практическим линейным

мой вариант
ИменаКолонокСтрокой = СтрСоединить(ИменаКолонок, ",");
ИменаКолонокСтрокой = ИменаКолонокСтрокой + ",Сумма";

Начисления.Индексы.Добавить(ИменаКолонокСтрокой);

ИсключаемыеСтрокиСоответствие = Новый Соответствие;
КлючСтроки = Новый Структура(ИменаКолонокСтрокой);

Для Каждого СтрокаНачислений Из Начисления Цикл
	
	Если ИсключаемыеСтрокиСоответствие[СтрокаНачислений] <> Неопределено Тогда 
		Продолжить;
	КонецЕсли;
	
	ЗаполнитьЗначенияСвойств(КлючСтроки, СтрокаНачислений);
	КлючСтроки.Сумма = -СтрокаПотенциальная.Сумма;
	
	ИсключатьСтроку = Ложь;
	Для каждого СтрокаПотенциальная Из Начисления.НайтиСтроки(КлючСтроки) Цикл 
		ИсключатьСтроку = Истина;
		Если ИсключаемыеСтрокиСоответствие[СтрокаПотенциальная] = Неопределено Тогда
			ИсключаемыеСтрокиСоответствие.Вставить(СтрокаПотенциальная);
			ИсключаемыеСтроки.Добавить(СтрокаПотенциальная);
		КонецЕсли;
	КонецЦикла;    
	Если ИсключатьСтроку Тогда      
		ИсключаемыеСтрокиСоответствие.Вставить(СтрокаНачислений);
		ИсключаемыеСтроки.Добавить(СтрокаНачислений);
	КонецЕсли;
КонецЦикла;
Показать
8. ZAOSTG 192 06.06.23 15:32 Сейчас в теме
Кстати
в релиз 3.1.25.136 1С снова подложили pork насчет производительности
сейчас доделываю обработку по подготовке регистров и в расширение добавлю ускорение
регистры по отпускам и аналитикам затрат - страшно медленно -на нашей базе это более 7 часов обработка первой части
и десяток часов когда пользователям уже можно работать...
9. ILM 241 08.06.23 10:58 Сейчас в теме
Валентин, напишите как с УПП переходили?
10. ZAOSTG 192 11.06.23 20:05 Сейчас в теме
(9)Мучительно ;)
1 - различное хранение данных. В ЗУП сделали "гениальную" реализацию - в один день можно сделать несколько кадровых операций. Добавляют секунду. в УПП такого нельзя. в итоге пришлось танцевать с бубном чтобы в УПП кадровая история
2 - обмены. как с кадровыми так и ведомости. Аналитика разрозненная, трансформации,
3 -скорость обмена. у нас ведомости на 6 000 чел уходя часами -механизм кривоватый, "дубовый" -пришлось его срочно ускорять

Перешли на ЗУП потому что "голова" решила что "будет как у нас!" Но одно дело офисный планкттон с его расчетом зп, другое строительная организация...
11. romandvin 13.08.25 17:32 Сейчас в теме
Здравствуйте )!!! Не подскажите для релиза ЗУПа Профа/Корпа 3.1.34.ХХ какое расширение нужно скачивать )?
Для отправки сообщения требуется регистрация/авторизация