Многие разработчики 1С сталкиваются с ситуацией, когда динамический список с большим объемом данных начинает работать очень медленно. Загрузка и особенно фильтрация списка могут занимать 5-10 секунд и более, что сильно раздражает пользователей и снижает эффективность работы. Часто возникает вопрос: может, дело в том, как мы накладываем отборы динамического списка? Что работает быстрее — Настройки.Отбор или ФиксированныеНастройки.Отбор? Давайте разберемся в этой проблеме, проанализируем реальный пример и найдем эффективное решение.
Первое, что нужно понять: с точки зрения производительности, нет никакой разницы между использованием обычных отборов (Настройки.Отбор) и фиксированных (ФиксированныеНастройки.Отбор). В обоих случаях при изменении фильтра платформа формирует и отправляет на сервер СУБД новый SQL-запрос. Разница между ними заключается исключительно в пользовательском интерфейсе:
Таким образом, если динамический список "тормозит", корень проблемы почти всегда кроется не в способе установки отбора, а в самом запросе, который лежит в основе списка, или в архитектуре данных. Основные "виновники" медленной работы:
В ИЕРАРХИИ. Для справочников с большим количеством элементов и сложной структурой эта операция может быть очень ресурсоемкой, так как требует рекурсивного обхода дерева элементов.Рассмотрим самую интересную и неочевидную причину замедления, с которой столкнулся автор в обсуждаемой теме. Его проблема решилась, когда он перенес условие фильтрации из параметров виртуальной таблицы в обычные отборы компоновщика данных. Давайте разберем, почему это сработало.
Представьте, что у нас есть запрос, получающий остатки товаров по конкретной папке номенклатуры. Сделать это можно двумя способами.
Способ 1: Фильтрация через параметр виртуальной таблицы
Мы передаем нужную папку как параметр прямо в виртуальную таблицу остатков.
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура,
ТоварыНаСкладахОстатки.ВНаличииОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(
,
Номенклатура В ИЕРАРХИИ (&РодительскаяПапка)) КАК ТоварыНаСкладахОстатки
В этом случае механизм платформы 1С сначала обращается к виртуальной таблице и просит ее вернуть данные, уже отфильтрованные по нашей папке. Только после этого результат этого подзапроса будет соединяться с другими таблицами в основном запросе.
Способ 2: Фильтрация через отбор компоновки (условие ГДЕ)
Мы получаем данные из виртуальной таблицы без параметров, а условие накладываем в секции ГДЕ основного запроса.
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Номенклатура,
ТоварыНаСкладахОстатки.ВНаличииОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
{ГДЕ
ТоварыНаСкладахОстатки.Номенклатура.* В ИЕРАРХИИ (&РодительскаяПапка)}
В этом случае платформа сначала формирует общий запрос ко всем таблицам, а потом СУБД применяет условие WHERE к общему, уже соединенному набору данных. Пользовательский отбор в настройках динамического списка работает именно по этому принципу.
В чем разница и почему второй способ оказался быстрее?
Как ни странно, иногда для оптимизатора запросов СУБД эффективнее работать с большими наборами данных и фильтровать их в конце, чем фильтровать каждую таблицу по отдельности, а потом соединять. Когда мы задаем жесткий параметр в виртуальной таблице, мы "связываем руки" оптимизатору СУБД, заставляя его следовать определенному, не всегда оптимальному плану. Когда же мы "забираем все подряд, а отборы делаем в настройках", мы даем СУБД больше свободы для построения наиболее эффективного плана выполнения запроса.
В случае из темы, автор изначально ставил параметр на папку в виртуальной таблице, а затем, при навигации по подпапкам, пользовательский отбор добавлял еще одно условие. Получался двойной избыточный отбор, который и приводил к тормозам. Убрав параметр из запроса и оставив только отбор в настройках, он сократил время выполнения с 4-5 секунд до 2.
Если вы столкнулись с медленной работой динамического списка, выполните следующие шаги для диагностики и оптимизации.
ГДЕ вложенных запросов используйте конструкции в фигурных скобках, например: {ГДЕ Поле.* КАК Поле}. Это позволит компоновщику правильно подставить условия и сократить выборку на более ранних этапах.
ПолучитьИсполняемуюСхемуКомпоновкиДанных() или инструменты, преобразующие динамический список в отчет СКД, чтобы программно получить итоговый текст запроса для анализа.
В заключение, помните, что оптимизация производительности — это всегда процесс исследования и экспериментов. Универсального рецепта нет, но описанный выше подход — перенос жестких условий из параметров запроса в гибкие отборы компоновки — является мощным инструментом, который часто помогает найти узкое место и значительно ускорить работу динамических списков.