Многие технические специалисты, работающие с конфигурациями 1С:Управление торговлей 11 (особенно версий 11.1, 11.2 и ранних 11.3), 1С:Комплексная автоматизация 2 или 1С:ERP, сталкиваются с проблемой: стандартный отчет «Задолженность клиентов по срокам» начинает формироваться крайне медленно. На крупных базах время ожидания может составлять несколько часов, а иногда процесс и вовсе завершается аварийно из-за нехватки памяти или переполнения TempDB на SQL-сервере.
В этой статье мы подробно разберем, почему это происходит, проанализируем внутренний код типового решения и рассмотрим практические способы оптимизации этого узла.
Проблема кроется в алгоритме распределения авансов и оплат по документам отгрузки, который выполняется «на лету» в момент формирования отчета. Рассмотрим ситуацию: отчет строится на данных двух основных регистров накопления: РасчетыСКлиентами (общие остатки) и РасчетыСКлиентамиПоДокументам (детализация до конкретных накладных).
В модуле отчета вызывается функция ПолучитьТаблицуПлатежей, которая, в свою очередь, обращается к процедуре РассчитатьДатыПлатежаКлиента в общем модуле ВзаиморасчетыСервер. Основной «мазохизм» (как выразился автор темы) заключается в использовании цикла, внутри которого постоянно выполняется запрос к менеджеру временных таблиц.
Проанализируем фрагмент этого кода:
Результат = Запрос.Выполнить;
Счетчик = 0;
Пока Не Результат.Пустой Цикл
Результат = Запрос.Выполнить;
// Внутри этого цикла система пытается сопоставить остатки
// и «вымыть» задолженность по алгоритму FIFO/LIFO
КонецЦикла;
Система создает временную таблицу ТаблицаОстатковКлиентов и начинает итерационно распределять суммы. Если у клиента накопилось огромное количество мелких документов, незакрытых копеечных остатков или возник «перекос» между регистрами (сумма по документам не сходится с общим итогом), количество итераций этого цикла начинает расти в геометрической прогрессии. С каждой новой итерацией менеджер временных таблиц разрастается, и SQL-серверу становится всё сложнее обрабатывать запросы.
Рассмотрим подробнее технические аспекты, которые заставляют этот код работать часами:
РасчетыСКлиентамиПоДокументам зависают записи, где СуммаОстаток равна нулю, но КОплатеОстаток или КОтгрузкеОстаток имеют ненулевые значения. Отчет пытается учесть эти «хвосты», что порождает лишние витки цикла.ЛЕВОЕ СОЕДИНЕНИЕ между неиндексированными временными таблицами убивает производительность.Прежде чем приступать к правке кода, попробуем решить проблему административными методами. Проанализируем состояние базы данных:
Корректировка задолженности, чтобы «схлопнуть» встречные авансы и долги. Чем меньше строк в остатках регистров, тем быстрее отработает цикл распределения.Тестирование и исправление с флагом Пересчет итогов. Иногда неверные итоги заставляют алгоритм FIFO «бесконечно» искать документы для распределения.Если данные в порядке, а отчет всё равно тормозит, перейдем к модификации кода процедуры РассчитатьДатыПлатежаКлиента. Рассмотрим шаги, которые помогут ускорить процесс:
Добавление индексов. Во всех местах, где создаются промежуточные временные таблицы (например, ТаблицаОстатковКлиентов, НовыеОстаткиКлиентов), необходимо добавить явное индексирование по ключевым полям: АналитикаУчетаПоПартнерам, ЗаказКлиента, Валюта.
Пример добавления индекса в коде:
|ПОМЕСТИТЬ ТаблицаОстатковКлиентов
|ИЗ
| НовыеОстаткиКлиентов КАК Остатки
|ИНДЕКСИРОВАТЬ ПО
| АналитикаУчетаПоПартнерам,
| ЗаказКлиента,
| Валюта
|;
Ограничение итераций. В более свежих версиях программ (например, в КА 2.4 для Казахстана) разработчики 1С добавили ограничение счетчика цикла (например, до 1000 итераций). Это не решает проблему производительности полностью, но предотвращает «зацикливание» и бесконечный рост TempDB. Можно внедрить аналогичный предохранитель самостоятельно.
Важно понимать, что в версиях УТ 11.4 и выше архитектура взаиморасчетов была кардинально пересмотрена. 1С отказалась от сложного распределения «на лету» в пользу новой модели «Взаиморасчеты онлайн». В этой модели данные о сроках задолженности и датах платежа хранятся в готовом виде в специализированных регистрах (например, ПлановыеОплатыКлиентов).
Если ваша конфигурация позволяет, рассмотрим возможность включения опции Взаиморасчеты онлайн (НСИ и администрирование -> Казначейство и взаиморасчеты). Это потребует перепроведения документов, но навсегда устранит проблему медленного формирования отчетов по дебиторке.
Проанализировав ситуацию, мы видим, что отчет «Задолженность клиентов по срокам» — это один из самых тяжелых узлов старой архитектуры УТ 11. Чтобы ускорить его работу, мы рекомендуем придерживаться следующего плана:
ВзаиморасчетыСервер через расширение.