Как ускорить запрос к виртуальной таблице «Хозрасчетный.ДвиженияССубконто»?

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

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

Оптимизация обращения к реквизитам субконто

Одной из самых частых причин медленной работы является обращение к реквизитам субконто через «точку», например: СубконтоКт3.УпрСтатьяБДР. Поскольку поле Субконто имеет составной тип данных, система 1С вынуждена выполнять LEFT JOIN со всеми таблицами справочников, которые могут выступать в роли этого субконто. Если в плане счетов для данного вида субконто разрешено множество типов, количество соединений в SQL-запросе может исчисляться десятками.

Рассмотрим, как правильно ограничить типы данных. Для этого мы должны использовать функцию ВЫРАЗИТЬ. Проанализируем пример кода:


|ВЫБРАТЬ
|   ФактБухгалтерия.Период,
|   ВЫРАЗИТЬ(ФактБухгалтерия.СубконтоКт3 КАК Справочник.СтатьиДоходовИРасходов).УпрСтатьяБДР КАК Статья
|ИЗ
|   РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(&ДатаНач, &ДатаКон, ...) КАК ФактБухгалтерия

Использование ВЫРАЗИТЬ жестко указывает платформе, с какой конкретно таблицей нужно выполнить соединение, что значительно сокращает нагрузку на SQL-сервер.

Замена условия «В ИЕРАРХИИ» на работу с временными таблицами

Конструкция В ИЕРАРХИИ крайне неэффективна внутри параметров виртуальной таблицы. Она заставляет СУБД выполнять вложенные подзапросы или строить огромные списки условий IN. Чтобы ускорить выполнение, мы рекомендуем заранее подготовить список всех элементов иерархии и поместить их во временную таблицу.

Разберем по шагам алгоритм оптимизации:

  1. Выбираем все элементы, входящие в нужную группу (иерархию), во временную таблицу ВТ_ЭлементыГруппы.
  2. Индексируем поле с ссылками во временной таблице.
  3. В основном запросе заменяем В ИЕРАРХИИ на обычное условие В, передавая массив ссылок, либо используем соединение с временной таблицей.

Пример оптимизированного условия в параметрах виртуальной таблицы:


// Вместо: СубконтоДт1 В ИЕРАРХИИ (&Группа)
// Используем предварительно выгруженный массив:
И СубконтоДт1 В (&МассивСсылокЭлементов)

Работа с полем «Регистратор» и представлениями

Часто программисты замечают, что добавление поля Регистратор в выборку замедляет запрос. Выясним причину: сама по себе ссылка на регистратор не должна тормозить выполнение Запрос.Выполнить(). Однако, если данные выводятся в отчет (особенно в СКД) или используется Регистратор.Представление, система начинает обращаться к таблицам всех типов документов, которые могут делать движения по регистру.

Важный совет: Если вам нужна только ссылка для возможности «провалиться» в документ из отчета, выбирайте только Регистратор. Избегайте конструкций Регистратор.Дата или Регистратор.Номер непосредственно в тяжелом запросе. Если эти данные необходимы, лучше получить их отдельным запросом к физическим таблицам документов после того, как основной объем данных уже отфильтрован.

Использование временных таблиц вместо «ОБЪЕДИНИТЬ ВСЕ»

Если ваш запрос содержит несколько блоков ОБЪЕДИНИТЬ ВСЕ, где каждый блок обращается к одной и той же виртуальной таблице с разными фильтрами, это создает избыточную нагрузку. Рассмотрим ситуацию: у вас есть общие фильтры (Организация, Период, Активность) и специфические (разные счета или субконто).

Проанализируем стратегию ускорения:

  1. Сначала выберем данные по общим фильтрам во временную таблицу ВТ_ДанныеРегистра. Это позволит «отсечь» лишние записи один раз.
  2. Далее будем работать уже с ВТ_ДанныеРегистра, применяя к ней специфические условия в блоках объединения.

Это позволит оптимизатору SQL-запросов работать с гораздо меньшим объемом данных на промежуточных этапах.

Физические таблицы против виртуальных

В некоторых случаях, когда требуется детализация до конкретной записи (периодичность Регистратор), виртуальная таблица ДвиженияССубконто может проигрывать в скорости обычным физическим таблицам. Посмотрим на структуру: физическая таблица РегистрБухгалтерии.Хозрасчетный уже содержит поля Субконто1, Субконто2 и т.д.

Если вам не требуется сложная логика получения остатков или развернутого сальдо, попробуйте написать запрос напрямую к основной таблице регистра с соединением к таблице субконто (_AccRgED) вручную. Это исключает «магию» платформы по сборке виртуальной таблицы и часто дает прирост производительности в 2–3 раза.

Резюме рекомендаций

Для достижения максимальной скорости придерживайтесь следующих правил:

← На главную