Оптимизация проведения документов списания партий в УПП 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 Конфигурации 1cv8 Бесплатно (free)

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

13.03.2024    3003    spyke    27    

42

Быстродействие типовой 1С

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

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

13.03.2024    5124    vasilev2015    19    

37

Анализируем SQL сервер глазами 1С-ника

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

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

1 стартмани

15.02.2024    7664    159    ZAOSTG    68    

96

Удаление строк из таблицы значений различными способами с замером производительности

HighLoad оптимизация Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Встал вопрос: как быстро удалить строки из ТЗ? Рассмотрел пять вариантов реализации этой задачи. Сравнил их друг с другом на разных объёмах данных с разным процентом удаляемых строк. Также сравнил с выгрузкой с отбором по структуре.

09.01.2024    6001    doom2good    48    

63

Опыт оптимизации 1С на PostgreSQL

HighLoad оптимизация Бесплатно (free)

При переводе типовой конфигурации 1C ERP/УТ/КА на PostgreSQL придется вложить ресурсы в доработку и оптимизацию запросов. Расскажем, на что обратить внимание при потерях производительности и какие инструменты/подходы помогут расследовать проблемы после перехода.

20.11.2023    8886    ivanov660    6    

76

ТОП проблем/задач у владельцев КОРП лицензий 1С на основе опыта РКЛ

HighLoad оптимизация Бесплатно (free)

Казалось бы, КОРП-системы должны быть устойчивы, быстры и надёжны. Но, работая в рамках РКЛ, мы видим немного другую картину. Об основных болевых точках КОРП-систем и подходах к их решению пойдет речь в статье.

15.11.2023    5117    a.doroshkevich    20    

72

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16198    skovpin_sa    14    

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

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