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