Динамический список. Оптимизация работы

05 января 2013

Файлы для загрузки:

Конфигурация с примерами из статьи

ПРЕАМБУЛА

В статье "Динамический список. Как это работает?" мы рассматривали работу платформы 1С:Предприятие 8.x с SQL-сервером при использовании динамического списка. Анализировали формируемые платформой SQL-запросы для различных действий с  объектом. Сегодня в статье будут предложены несколько способов его оптимизации работы. Итак, приступим!

Примечание: объект формы "Динамический список" появился в платформе 8.2. Его использование возможно только для управляемых форм.

Несколько динамических списков на форме

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

Закладки

Чтобы список формировался только при обращении к соответствующей закладке, будем передавать в запрос динамического списка параметр "Формировать". Если его значение ИСТИНА, тогда список формируется, иначе запрос возвращает пустой результат. Для этого изменим запрос объекта произвольным образом, добавив в секцию "ГДЕ" следующее выражение:

Запрос

При создании формы и при изменении текущей страницы будем вызывать процедуру, устанавливающую значение параметров для двух динамических списков формы:

  1. "Список".
  2. "ТоварыБезДинамическогоСчитывания".

Процедура, устанавливающая параметры, выглядит следующим образом:

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

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

Единственным минусом такого подхода является то, что запросы к SQL-серверу все равно  будут выполнены. Почему же тогда SQL-запрос отрабатывается быстрее? Давайте посмотрим на план выполнения запросов до и после оптимизации.

План запроса

Из рисунка видно, что запрос упростился до одного действия - "Constant Scan". Это действие занимает мало ресурсов SQL-сервера. 

Для того, чтобы SQL-запрос вообще не был сформирован до момента обращения пользователя к динамическому списку, наилучшим вариантом будет вынести его в отдельную форму и открывать по необходимости. Например, создадим для каждого динамического списка отдельную форму: "ОбычныйСписок" и "ТоварыБезДинамическогоСчитывания" . Добавим новую форму "ФормаСпискаОтдельныеФормы", в которой будут содержаться две команды для перехода на созданные ранее формы динамических списков. Эта форма выглядит следующим образом:

Навигация по формам динамических списков

 При активации команды будет произведен переход на соответствующую форму. И только в этот момент будет осуществлен запрос к базе данных для формирования динамического списка. В формы "ОбычныйСписок" и "ТоварыБезДинамическогоСчитывания" была добавлена команда "Назад", открывающая исходную форму "ФормаСпискаОтдельныеФормы".

Посмотреть вышеописанный способ открытия отдельных форм динамического списка Вы можете в демонстрационной конфигурации (ссылка для загрузки в конце статьи) и на следующем видео:

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

Может возникнуть вопрос: "Для чего были приведены оба способа оптимизации работы динамических списков, если второй эффективнее?". Первый способ нужно применять в тех случаях, когда нельзя разделить функционал на несколько форм.

СЛОЖНЫЕ ПРОИЗВОЛЬНЫЕ ЗАПРОСЫ ДИНАМИЧЕСКОГО СПИСКА

Относительно использования произвольных запросов в динамическом списке. Тут нужно соблюдать правила написания оптимальных запросов к базе данных. Поскольку использовать временные таблицы и объединения в запросах нельзя (ограничение платформы), то единственный путь создания сложных запросов является применение вложенных запросов. Их использование может привести к существенному росту нагрузки на сервер СУБД. Это можно продемонстрировать изменением плана запроса до и после использования вложенных запросов.

До использования вложенных запросов:

План запроса

После использования вложенных запросов (часть плана выполнения):

План запроса

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

Примечание: существуют и другие причины неоптимальных запросов: использование виртуальных таблиц без указания параметров, соединение нескольких вложенных запросов и прочее.

ВЫВОДЫ

В статье были рассмотрены способы оптимизации работы динамических списков на управляемых формах. Частично была охвачена тема применения произвольных запросов.

Самое главное, что следует из всего вышесказанного - не стоит использовать сложные запросы в динамических списках, иначе теряется весь смысл этого объекта. Вместо того, чтобы получать данные для быстрого просмотра с возможностью отбора и сортировки, мы получим "отчет", построенный не самым оптимальным образом и с узкими возможностями.

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

На этом все, спасибо за внимание! 


comments powered by Disqus