Обработка «Формирование заказов по потребностям» — один из наиболее ресурсоемких механизмов в современных типовых конфигурациях 1С (таких как 1С:ERP Управление предприятием, Комплексная автоматизация и Управление торговлей). При переходе с Шага 1 на Шаг 2 пользователи часто сталкиваются с критическим замедлением работы системы. Время ожидания может составлять от нескольких минут до нескольких часов, особенно если объем анализируемой номенклатуры велик (например, порядка 80 000 позиций и более).
Основным «виновником» этой проблемы является функция ТаблицаЗапасы, расположенная в модуле менеджера ОбеспечениеПотребностей. При проведении трассировки времени выполнения выясняется, что именно в этой функции происходит выгрузка результата тяжелого динамического запроса в таблицу значений. В этой статье мы подробно разберем, почему возникает данная проблема, и рассмотрим эффективные методы ее решения.
Давайте проанализируем ситуацию. Запрос в функции ТаблицаЗапасы является универсальным и монолитным. Он пытается одновременно рассчитать все возможные варианты обеспечения, сопоставить текущие остатки, ожидаемые поступления и потребности по всем заказам. В результате SQL-серверу приходится выполнять гигантский объем соединений (LEFT JOIN) и подзапросов по таблицам с сотнями тысяч или миллионами записей.
Когда мы пытаемся выполнить расчет для 80 000 позиций номенклатуры «в лоб» без предварительной подготовки данных, СУБД тратит колоссальные ресурсы на построение оптимального плана выполнения запроса. Ситуация усугубляется, если в базе не настроено регулярное обслуживание или планировщик СУБД ошибается в оценке количества строк.
Как показывает практика, выполнение реиндексации на SQL-сервере способно дать мгновенный прирост производительности. Один из участников обсуждения отметил, что после реиндексации базы данных и ручного создания индексов на стороне MS SQL Server скорость выполнения тяжелого запроса увеличилась в три раза (время сократилось с 8 минут до 2 минут 38 секунд).
Важное предостережение: создание индексов напрямую в MS SQL Server или PostgreSQL в обход платформы 1С крайне не рекомендуется. При первом же обновлении конфигурации или реструктуризации таблиц базы данных все ваши ручные индексы на стороне СУБД будут безвозвратно удалены платформой.
Чтобы решить эту проблему правильно и навсегда, выполним индексацию средств разработки 1С через Конфигуратор. Давайте разберем по шагам, какие объекты базы данных требуют внимания:
ВариантыОбеспеченияТоваров. Перейдем к его измерениям и для ключевых полей (например, Номенклатура, Склад) установим свойство «Индексировать».НастройкаПоддержанияЗапасов.ЗапасыИПотребности и РаспределениеЗапасов. Измерения, по которым накладываются отборы в обработке обеспечения потребностей, обязательно должны быть проиндексированы.Помимо настройки индексов в Конфигураторе, критически важно настроить регулярные регламентные процедуры на сервере СУБД. Особое внимание следует уделить обновлению статистики (команда UPDATE STATISTICS для MS SQL). Если база данных работает под управлением PostgreSQL, планировщик запросов особенно чувствителен к актуальности статистики. Рекомендуется настроить ежедневный запуск регламентного задания для обновления статистики по таблицам обеспечения.
Проанализируем классическую ошибку проектирования тяжелых запросов. Часто разработчики пытаются решить задачу в рамках одного огромного запроса со сложной цепочкой левых соединений. На малых объемах данных это работает быстро, но при росте базы производительность резко падает.
Правильный архитектурный подход заключается в декомпозиции задачи. Вместо того чтобы сразу выполнять тяжелые расчеты для всей базы, мы должны отсечь лишние данные на самом первом этапе. Посмотрим на концептуальный пример декомпозиции запроса в 1С:
// Шаг 1: Выбираем только те позиции номенклатуры и склады, по которым реально есть потребности
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ЗапасыИПотребности.Номенклатура КАК Номенклатура,
| ЗапасыИПотребности.Склад КАК Склад
|ПОМЕСТИТЬ ВТ_ОтфильтрованнаяНоменклатура
|ИЗ
| РегистрНакопления.ЗапасыИПотребности КАК ЗапасыИПотребности
|ГДЕ
| ЗапасыИПотребности.Номенклатура В (&СписокНоменклатуры)
| И ЗапасыИПотребности.Склад = &ВыбранныйСклад;
|
|////////////////////////////////////////////////////////////////////////////////
|// Шаг 2: Выполняем расчеты только для отфильтрованного набора данных
|ВЫБРАТЬ
| ВТ.Номенклатура,
| ВТ.Склад,
| ЕСТЬNULL(Цены.Цена, 0) КАК Цена,
| ЕСТЬNULL(Остатки.ВНаличии, 0) КАК Остаток
|ИЗ
| ВТ_ОтфильтрованнаяНоменклатура КАК ВТ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(,, Номенклатура В (ВЫБРАТЬ Номенклатура ИЗ ВТ_ОтфильтрованнаяНоменклатура)) КАК Остатки
| ПО ВТ.Номенклатура = Остатки.Номенклатура И ВТ.Склад = Остатки.Склад";
Использование временных таблиц позволяет уменьшить размер выборки на порядки. Сначала мы создаем легкую временную таблицу ВТ_ОтфильтрованнаяНоменклатура, в которой содержится только целевой список товаров. Все последующие тяжелые левые соединения выполняются уже не со всей гигантской таблицей регистра, а с ограниченным набором данных из временной таблицы. На практике такой подход увеличивает скорость выполнения обработки в 10 и более раз.
Рассмотрим возможности оптимизации, заложенные разработчиками фирмы 1С в актуальных версиях конфигураций ERP 2.5, Комплексная автоматизация 2.5 и Управление торговлей 11.5. В настройках системы предусмотрено два режима обеспечения потребностей: расширенный и упрощенный.
Если бизнес-процессы вашей компании позволяют отказаться от сложных схем расчета запасов (таких как расчет по статистике продаж, поддержание сложных минимумов и максимумов по графикам поставок), переключите склад на упрощенный режим обеспечения. В этом режиме программа не строит тяжелые графики движения товаров, а расчет дефицита выполняется по прямой формуле «Потребность минус Остаток». Это позволяет существенно разгрузить функцию ТаблицаЗапасы и ускорить работу алгоритма.
Интерактивная работа пользователя с обработкой по расчету потребностей для 80 000 позиций — это заведомо неэффективное решение. Заставлять закупщика сидеть перед монитором в ожидании окончания расчетов не имеет смысла. Оптимальный вариант — перевести процесс в фоновый режим:
РегламентныеЗадания) для автоматического расчета потребностей и формирования предварительных заказов поставщикам в ночное время.Подводя итог, можно утверждать, что проблема низкой скорости формирования заказов по потребностям успешно решается за счет комплекса мер: своевременного обслуживания СУБД, индексации регистров средствами 1С, перевода запросов на рельсы декомпозиции с использованием временных таблиц и автоматизации процесса в фоновом режиме.