При переходе с конфигураций на обычных формах (например, БП 2.0) на управляемые (БП 3.0) разработчики часто сталкиваются с парадоксальной ситуацией: запрос, который в старой базе отрабатывал за доли секунды, в новой «вешает» систему на полминуты или дольше. При этом консоль запросов может показывать время выполнения в несколько миллисекунд, но пользователь продолжает ждать. Разберем детально, почему так происходит, и проанализируем неочевидные факторы влияния платформы 1С:Предприятие 8.3.
Первое, на что мы должны обратить внимание — это разница между чистым временем исполнения запроса на сервере СУБД (или движком файловой базы) и общим временем ожидания результата. Рассмотрим ситуацию: автор темы указывает, что консоль зафиксировала время 0.035 с, но реальное ожидание составило 30 секунд.
Выясним причину этого разрыва. В управляемом приложении 1С реализована строгая клиент-серверная архитектура (даже в файловом варианте). Когда запрос завершается, данные должны быть:
В управляемых формах механизмы вывода данных в таблицы гораздо «тяжелее», чем в обычных. Если ваш запрос возвращает много колонок со ссылочными типами, платформа для каждой ячейки пытается получить текстовое представление. В обычном приложении это происходило быстро за счет прямого доступа к кэшу, а в управляемом — может вызывать дополнительные обращения к серверу или ресурсоемкие вычисления ПРЕДСТАВЛЕНИЕ() для каждой ссылки.
Проанализируем структуру запроса, приведенного в примере. Мы видим массивный вложенный запрос в секции ИЗ (подзапрос РеестрСчетовФактур), внутри которого есть еще один вложенный запрос (ВложенныйЗапрос) с операторами ОБЪЕДИНИТЬ ВСЕ.
Для платформы 8.3 и новых версий оптимизаторов СУБД такая структура является «ядом». Рассмотрим, почему стоит отказаться от вложенных запросов в пользу временных таблиц:
Nested Loops или сканировать весь объем данных.Перепишем проблемный участок, используя МенеджерВременныхТаблиц. Вместо гигантского вложенного запроса сделаем так:
// Поместим данные по авансовым отчетам во временную таблицу
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
| АвансовыйОтчетТовары.СчетФактура КАК СчетФактура,
| АвансовыйОтчетТовары.Поставщик КАК Контрагент,
| АвансовыйОтчетТовары.Ссылка КАК АО
|ПОМЕСТИТЬ ВТ_КонтрагентыПоАО
|ИЗ
| Документ.АвансовыйОтчет.Товары КАК АвансовыйОтчетТовары
|... (аналогично для ТЧ Прочее)";
Использование Временных Таблиц позволяет платформе четко понимать объем данных и использовать индексы при последующих соединениях, что критически важно для управляемого приложения.
В тексте запроса автора мы видим конструкции: РеестрСчетовФактур.Контрагент.НаименованиеПолное и СчетФактураПолученный.ДокументОснование.ДоговорКонтрагента.Владелец. Рассмотрим, к чему это приводит.
Каждая «точка» в запросе — это неявное левое соединение (LEFT JOIN) с соответствующей таблицей. В БП 3.0 объекты стали гораздо сложнее, чем в БП 2.0 (больше реквизитов, больше табличных частей). В файловом режиме при большом количестве таких неявных соединений нагрузка на дисковую подсистему возрастает экспоненциально.
Рекомендация: Если вам нужно получить данные контрагента, лучше один раз явно присоединить таблицу Справочник.Контрагенты и выбрать нужные поля, чем заставлять платформу генерировать десятки неявных связей.
Важный аспект, упомянутый в обсуждении — тип носителя. Управляемое приложение 1С в файловом режиме работает с базой данных 1Cv8.1CD гораздо интенсивнее в плане операций ввода-вывода (IOPS). Рассмотрим причины:
Если конфигурация БП 2.0 комфортно работала на обычном HDD, то БП 3.0 на управляемых формах требует обязательного наличия SSD. Как было замечено в сообщении 25, переход на новую версию должен сопровождаться техническим апгрейдом.
Выясним еще одну причину задержек — разницу в запуске встроенных и внешних отчетов. В управляемом приложении при запуске внешнего отчета происходит процесс компиляции его контекста «на лету». Рассмотрим по шагам:
Для ускорения работы рекомендуется встраивать часто используемые тяжелые отчеты непосредственно в конфигурацию или в расширение. Это позволяет платформе выполнить часть подготовительных действий заранее, при запуске сеанса или обновлении конфигурации БД, а не в момент нажатия кнопки «Сформировать».
Проанализировав ситуацию, мы можем составить алгоритм действий для оптимизации:
Запрос.Выполнить() мало, а общее время велико — проблема в передаче данных на клиент или в их отрисовке. Ограничьте количество выводимых колонок и строк.Таким образом, замедление в управляемых формах — это чаще всего не проблема самого SQL-движка, а вопрос архитектуры доставки данных от сервера к пользователю и возросшей сложности метаданных современных конфигураций.