Почему тормозит динамический список в 1С и как его ускорить?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Многие разработчики 1С сталкиваются с ситуацией, когда динамический список с большим объемом данных начинает работать очень медленно. Загрузка и особенно фильтрация списка могут занимать 5-10 секунд и более, что сильно раздражает пользователей и снижает эффективность работы. Часто возникает вопрос: может, дело в том, как мы накладываем отборы динамического списка? Что работает быстрее — Настройки.Отбор или ФиксированныеНастройки.Отбор? Давайте разберемся в этой проблеме, проанализируем реальный пример и найдем эффективное решение.

Выясняем причину: дело не в отборах, а в запросе

Первое, что нужно понять: с точки зрения производительности, нет никакой разницы между использованием обычных отборов (Настройки.Отбор) и фиксированных (ФиксированныеНастройки.Отбор). В обоих случаях при изменении фильтра платформа формирует и отправляет на сервер СУБД новый SQL-запрос. Разница между ними заключается исключительно в пользовательском интерфейсе:

Таким образом, если динамический список "тормозит", корень проблемы почти всегда кроется не в способе установки отбора, а в самом запросе, который лежит в основе списка, или в архитектуре данных. Основные "виновники" медленной работы:

Ключевой момент: параметры виртуальных таблиц vs отборы компоновки

Рассмотрим самую интересную и неочевидную причину замедления, с которой столкнулся автор в обсуждаемой теме. Его проблема решилась, когда он перенес условие фильтрации из параметров виртуальной таблицы в обычные отборы компоновщика данных. Давайте разберем, почему это сработало.

Представьте, что у нас есть запрос, получающий остатки товаров по конкретной папке номенклатуры. Сделать это можно двумя способами.

Способ 1: Фильтрация через параметр виртуальной таблицы

Мы передаем нужную папку как параметр прямо в виртуальную таблицу остатков.


ВЫБРАТЬ
    ТоварыНаСкладахОстатки.Номенклатура,
    ТоварыНаСкладахОстатки.ВНаличииОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(
            ,
            Номенклатура В ИЕРАРХИИ (&РодительскаяПапка)) КАК ТоварыНаСкладахОстатки

В этом случае механизм платформы 1С сначала обращается к виртуальной таблице и просит ее вернуть данные, уже отфильтрованные по нашей папке. Только после этого результат этого подзапроса будет соединяться с другими таблицами в основном запросе.

Способ 2: Фильтрация через отбор компоновки (условие ГДЕ)

Мы получаем данные из виртуальной таблицы без параметров, а условие накладываем в секции ГДЕ основного запроса.


ВЫБРАТЬ
    ТоварыНаСкладахОстатки.Номенклатура,
    ТоварыНаСкладахОстатки.ВНаличииОстаток
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
{ГДЕ
    ТоварыНаСкладахОстатки.Номенклатура.* В ИЕРАРХИИ (&РодительскаяПапка)}

В этом случае платформа сначала формирует общий запрос ко всем таблицам, а потом СУБД применяет условие WHERE к общему, уже соединенному набору данных. Пользовательский отбор в настройках динамического списка работает именно по этому принципу.

В чем разница и почему второй способ оказался быстрее?

Как ни странно, иногда для оптимизатора запросов СУБД эффективнее работать с большими наборами данных и фильтровать их в конце, чем фильтровать каждую таблицу по отдельности, а потом соединять. Когда мы задаем жесткий параметр в виртуальной таблице, мы "связываем руки" оптимизатору СУБД, заставляя его следовать определенному, не всегда оптимальному плану. Когда же мы "забираем все подряд, а отборы делаем в настройках", мы даем СУБД больше свободы для построения наиболее эффективного плана выполнения запроса.

В случае из темы, автор изначально ставил параметр на папку в виртуальной таблице, а затем, при навигации по подпапкам, пользовательский отбор добавлял еще одно условие. Получался двойной избыточный отбор, который и приводил к тормозам. Убрав параметр из запроса и оставив только отбор в настройках, он сократил время выполнения с 4-5 секунд до 2.

Пошаговый план по ускорению динамического списка

Если вы столкнулись с медленной работой динамического списка, выполните следующие шаги для диагностики и оптимизации.

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

В заключение, помните, что оптимизация производительности — это всегда процесс исследования и экспериментов. Универсального рецепта нет, но описанный выше подход — перенос жестких условий из параметров запроса в гибкие отборы компоновки — является мощным инструментом, который часто помогает найти узкое место и значительно ускорить работу динамических списков.

← На главную