Оптимизация проведения документов списания партий в УПП 1.3

09.09.21

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

Почти в каждой конфигурации УПП 1.3 (возможно, и в УТ 10.3) есть медленный запрос, тормозящий проведение документа списания. Данная публикация раскрывает места вызова данного запроса и приводит пример оптимизации. Пример показывает результаты проведения документа «Реализация товаров и услуг», но метод работает и для других документов списания партий.

Примерно, в 2019 году я отлаживал некоторую разработку в УТ 10.3.15.9, в ходе которой проводил документ «Реализация товаров и услуг» (РТУ). После многочисленных проведений и я обнаружил, что иногда при проведении происходит длительное зависание (минута-две), когда обычно РТУ проводится в течение 10 секунд. В конфигураторе замер производительности показал топовую строку кода:

 

УправлениеЗапасамиПартионныйУчет.ДвижениеПартийТоваров(Ссылка, Движения.СписанныеТовары.Выгрузить(),,,,,,,,,,Отказ);

Другие детали конфигуратор скрыл, на тот момент у меня отсутствовал доступ к технологическому журналу (ТЖ), к СУБД тоже отсутствовал (хотя было известно, что это MS SQL Server 2008 R2), и задача была другая, поэтому дальнейшее расследование остановлено.

Прошло время (2018, 2019, 2020), и вот в 2021 году поступила задача: в системе УПП 1.3.162 медленно проводится реализация.

Для начала проверен программный код, и обнаружена следующая конструкция:

 

 

 

 

Что мы наблюдаем: в модуле РТУ создается COM-соединение с базой MySQL (которая может оказаться достаточно далеко, и связь с которой может оказаться достаточно медленной и с прерываниями), выполняется команда в базе MySQL(которая тоже может быть длительной), и все это выполняется два раза: в процедурах ПередЗаписью, ОбработкаПроведения.

Очевидно, что данный функционал следует перестроить архитектурно, что в первую очередь и сделано:

1) создан регистр сведений «Документы интеграции», в который записывается информация при проведении РТУ;

2) создано регламентное задание, которое соединяется с базой MySQL и выполняет необходимые команды.

Данное изменение перестало мешать и оказалось полезным для разгрузки времени проведения, но не было основной причиной.

На этот раз доступ к ТЖ был, собраны события: CALL, SCALL, DBMSSQL, EXCP.

ТЖ показал:

 
 CALL
 
 DBMSSQL

 

То есть тормоза находятся в общем модуле УправлениеЗапасамиПартионныйУчет.

Конечная строка: Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);

Из данных строк ТЖ получаем, что на СУБД внезапно запрос выполняется медленно. Но что может вызывать такое непредсказуемое поведение?

Через Extended Events собраны планы запросов (к сожалению, уже не сохранились, приложить нечего), планы генерируются распараллеленными, поиск в таблицах выполняется по индексам, ничего особенно, но как-то медленно происходят соединения таблиц (60-90% времени), причем такие замедления бывают иногда, а часто в основном быстро без задержек.

Остается смотреть текст запроса:

 
 Процедура ЗаполнитьЗапросПартийНаСкладахУпр

 

В запросе остатки соединяются несколько раз с регистром СписанныеТовары.

Нужно отметить, что объем данных регистров достаточный:

РегистрНакопления.ПартииТоваровНаСкладах: 4 млн. строк.

РегистрСведений.СписанныеТовары: 3 млн. строк.

РегистрНакопления.ПартииТоваровНаСкладах.Итоги: 100 тыс. строк.

Казалось, что достаточно чаще пересчитывать итоги, и всегда будет использоваться только 100 тыс. строк, то есть только итоги вместо основного регистра, но функциональная специфика работы организации такова, что старые периоды редактируют почти каждый день много раз, поэтому в запросе используется именно основной регистр с 4 млн. строк.

И вот мы представляем, как 4 млн. строк соединяются с 3 млн. строк несколько раз, пусть даже по индексам, но поиск по таким объемам уже дает о себе знать, и похоже в этом и причина.

И тогда я задался мыслью: а зачем каждый раз обращаться в регистр СписанныеТовары, если товаров всего пару десятков для РТУ и их можно получить всего один раз для дальнейшего использования! И такая временная таблица уже даже присутствует в программном коде — это переменная ТаблицаСписания, которую достаточно передать в запрос в качестве параметра.

 

 

И теперь можно перестроить запрос с использованием существующей таблицы, избавившись от многоразового подтягивания многомилионного регистра СписанныеТовары.

 
 Процедура КС_ЗаполнитьЗапросПартийНаСкладахУпр_РТУ

 

Нужно еще отметить: так как данная оптимизация значительно затрагивает функционал, повышает риск сбоев в остатках, то пришлось потратить некоторое время на проверку после массового проведения документов. Сверяли остатки двух баз: остатки до с остатками после оптимизации.

 

Итог

За день проводится около 200 РТУ.

Результаты до оптимизации: каждая пятая РТУ проводилась около минуты-полторы, каждая третья РТУ проводилась около 15-30 секунд.

Результат после оптимизации: за день около 2-3 РТУ проводится в течение 20 секунд, остальные проводятся менее 10 секунд.

Результаты проведения других документов не проверял, но суть та же.

УПП 1.3 оптимизация проведение реализации списание партий ускорение проведения списания запросов

См. также

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

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

18.02.2025    3727    ivanov660    35    

54

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

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

24.06.2024    6656    ivanov660    12    

57

HighLoad оптимизация Программист Платформа 1С v8.3 Бесплатно (free)

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

06.06.2024    11434    Evg-Lylyk    63    

45

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

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

13.03.2024    5931    spyke    29    

51

HighLoad оптимизация Программист Платформа 1С v8.3 Бесплатно (free)

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

13.03.2024    8828    vasilev2015    22    

44

HighLoad оптимизация Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 1C:Бухгалтерия Абонемент ($m)

Обработка для простого и удобного анализа настроек, нагрузки и проблем с SQL сервером с упором на использование оного для 1С. Анализ текущих запросов на sql, ожиданий, конвертация запроса в 1С и рекомендации, где может тормозить.

10 стартмани

15.02.2024    14510    287    ZAOSTG    99    

120
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. 1c-intelligence 12872 10.09.21 07:43 Сейчас в теме
А можно:
1. Выполнять списание партий фоновым заданием, вне транзакции проведения документа;
2. Не списывать партии при проведении документа, делать это регл. заданием;
3. Перейти на РАУЗ;
4. Свернуть базу.
3. info1i 239 10.09.21 09:54 Сейчас в теме
(1) 1,2. Можно, но требует более дорогого продумывания, не всегда это возможно, много касс списывают с одного склада товар, скоростная конкуренция за актуальные остатки высокая, требует переобучения пользователей (хочется ведь видеть сразу результат проведения, а не когда закончится фоновое).
3,4. Дорого, порой даже значительно дороже текущего решения. И заказчик не готов резать свою базу на части, чтобы потом смотреть ее в разных местах.
2. MiniGrad2014 10.09.21 08:32 Сейчас в теме
Не знаете, в УТ 10-ой может быть что-то подобное?
4. info1i 239 10.09.21 09:56 Сейчас в теме
(2) Да, может - это то, с чего началась история. Ориентируйтесь на указанные мной строчки кода и найдите текст запроса, который получает партии перед списанием.
5. kauksi 217 09.12.21 10:48 Сейчас в теме
Очевидно что это какая то специфичная УПП с встроенным бит-Финансом, поэтому это косяк разработчиков БФ
6. wolder 133 02.08.23 05:41 Сейчас в теме
А что за функция : ПараметрыЗапроса_ДатаОприходования = ПолучитьДанныеДляЗапроса_ДокументОприходованияДата(СпособОценкиМПЗ,"ПартииТоваровНаСкладах");

Возвращает структуру? В Ут 10.3 её нет. Судя по синтаксису это не родная функция от конфигурации.
Можете её выложить?
7. info1i 239 02.08.23 23:33 Сейчас в теме
(6)
Функция ПолучитьДанныеДляЗапроса_ДокументОприходованияДата(СпособОценкиМПЗ, ПсевдонимТаблицы)
	флПоСредней = ложь;
	Если ТипЗнч(СпособОценкиМПЗ)=Тип("Строка") И ВРег(СпособОценкиМПЗ) = "ПО СРЕДНЕЙ" Тогда
		флПоСредней = истина;
	КонецЕсли;
	Если флПоСредней Тогда
		стрПолеВыборки 		= "";
		стрПолеСортировки 	= "";
	Иначе
		стрПолеВыборки 		= ПсевдонимТаблицы+".ДокументОприходования.Дата КАК ДокументОприходованияДата,";
		стрПолеСортировки 	= "ДокументОприходованияДата"+ ?(СпособОценкиМПЗ = "ЛИФО", " Убыв","") + ",";
	КонецЕсли;
	Возврат новый Структура("ДокОприходованияДата_Выбор,ДокОприходованияДата_Сортировка",стрПолеВыборки,стрПолеСортировки);
КонецФункции
Показать
Оставьте свое сообщение