Чего только не придумывалось, чтобы как то решить эту проблему – это и отсроченное списание партий ночью и сверхчастое обновление статистики SQL, но почему-то среди общих рекомендаций не встречается оптимизация именно типового кода УПП.
В типовой УПП механизм списания партий реализован очень давно. Его основная логика не менялась как минимум с релиза 1.2.16 по 1.3.26, т.е 4 года. Скорее всего за эти годы не раз сменялись внутренние стандарты разработки прикладных решений в самой 1с. На текущий момент не рекомендуется использовать в запросе соединение с подзапросом, но так как код был достаточно старый, то такое соединение использовалось до релиза 1.3.26. Ситуация наконец была исправлена в релизе 1.3.27, но как показала личная практика это решение не принесло значимой пользы при больших нагрузках.
Задолго до релиза 1.3.27 я столкнулся с тем, что на предприятии имеющем розничное подразделение с несколькими сотнями документов «Отчет о розничных продажах» в день со средним количеством строк порядка 100 уже невозможно было провести весь объем документов даже за окно доступное ночью (работа базы была почти круглосуточная, но ночью нагрузка значительно меньше). В среднем документ «Отчет о розничных продажах» проводился по 3-5 минут, если кто-то вдруг решил перепровести документ днем, то время проведения могло доходить до 30 минут, что конечно сильно тормозило других пользователей. Т.е. ситуация стала абсолютно невыносимой. Доступа к серверу SQL в той организации я не имел, поэтому у меня был один выход – попробовать оптимизировать типовой код.
Для поиска узкого места выгрузил копию базы в файловую (на тот момент она еще выгружалась, достаточно было очистить регистр сведений «Версии объектов»). Отладчиком был найден типовой код на котором висело по минуте – это были банальные строки Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам) в процедурах ПолучитьДеревоПартийНаСкладахУпр, ПолучитьДеревоПартийНаСкладахБух, ПолучитьДеревоПартийНаСкладахНал общего модуля УправлениеЗапасамиПартионныйУчет.
Посмотрев текст запроса и грубо упростив его получаем:
ВЫБРАТЬ
ПартииТоваровНаСкладах.Номенклатура
ИЗ
РегистрСведений.СписанныеТовары КАК СписанныеТовары
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах.Остатки(
&Дата,
Номенклатура В
(ВЫБРАТЬ
РегистрСведений.СписанныеТовары.Номенклатура
ИЗ
РегистрСведений.СписанныеТовары
ГДЕ
РегистрСведений.СписанныеТовары.Регистратор = &Ссылка)) КАК ПартииТоваровНаСкладах
ПО СписанныеТовары.Номенклатура = ПартииТоваровНаСкладах.Номенклатура
ГДЕ
СписанныеТовары.Регистратор = &Ссылка
Что мне здесь не понравилось:
1) Из регистра сведений «Списанные товары» информация выбирается не один раз, а несколько
2) Получается что сначала идет соединение, а только потом отбор условием ГДЕ СписанныеТовары.Регистратор = &Ссылка.
Обе эти проблемы решаются элементарно – перед
Возврат Запрос.Выполнить().Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
В трех вышеуказнных функция вставляем код
Запрос.Текст =
"ВЫБРАТЬ
| *
|ПОМЕСТИТЬ СписанныеТовары
|ИЗ
| РегистрСведений.СписанныеТовары
|ГДЕ
| Регистратор В (&ОсновнойДокумент, &Ссылка)
|ИНДЕКСИРОВАТЬ ПО Номенклатура;
|
|" + СтрЗаменить(Запрос.Текст, "РегистрСведений.СписанныеТовары", "СписанныеТовары");
Этот сверхпростой код принес колоссальный эффект – документы которые проводились по 3-5 мин стали проводиться по 20-40 секунд. Пробовал добавлять различные индексы кроме Номенклатуры и играться с условиями – где-то это давало дополнительный прирост местами даже в 2 раза.
Этот код ускоряет весь механизм списания партий. На других документах списывающих партии время проведения так же значительно снизилось.
Так же я пробовал эту модификацию на текущем месте работы – здесь не было особых проблем с проведением документов списывающих партии, тем не менее, код дал ускорение при восстановлении партионной последовательности при закрытии месяца. Особенно это было заметно в случае когда сервер 1с длительное время работал без перезагрузки. При переходе на релиз 1.3.27 раз уж был изменен типовой код в этом месте решил отказаться от своей доработки, но на следующий же день получил несколько звонков от сбыта, что реализации стали проводиться заметно дольше. Сейчас уже более полугода работаем на более мощном сервере, но повторять эксперимент уже нет желания.
Позже на просторах интернета был найден и другой способ – сверхчастое обновление статистики только по нужным регистрам.
Дополнено 25.06.2013 - Теперь исправление запроса корректно и для ордерной схемы. Код раскрашен разукрашкой - //infostart.ru/public/19856/