Почему перенос условий в параметры виртуальной таблицы СрезПоследних замедляет запрос и как это исправить

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Существует распространенное правило оптимизации запросов в платформе 1С:Предприятие 8.3 — все отборы по измерениям и периодам необходимо передавать напрямую в параметры виртуальных таблиц, а не оставлять в секции ГДЕ. Однако на практике слепое следование этому правилу может не ускорить, а существенно замедлить выполнение запроса (вплоть до нескольких раз), особенно в файловых базах данных (1CD) и при работе с периодическими регистрами сведений. Разберем детально, почему это происходит и как правильно оптимизировать запросы.

Причина 1. Подмена логики: физическая таблица против СрезПоследних

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


ВЫБРАТЬ
    План.Клуб КАК Клуб,
    План.Вид КАК Вид,
    План.Сумма КАК Сумма,
    План.Период КАК Период
ИЗ
    РегистрСведений.План КАК План
ГДЕ
    План.Период >= &ВыбНач И План.Период <= &ВыбКон
    И План.Клуб = &ВыбКлуб
    И План.Вид В ИЕРАРХИИ(&ВыбВид)

После попытки «оптимизации» запрос был переписан на обращение к виртуальной таблице СрезПоследних:


ВЫБРАТЬ
    План.Клуб КАК Клуб,
    План.Вид КАК Вид,
    План.Сумма КАК Сумма,
    План.Период КАК Период
ИЗ
    РегистрСведений.План.СрезПоследних(&ВыбКон, Клуб = &Клуб И Вид В ИЕРАРХИИ(&ВыбВид)) КАК План

Рассмотрим, что произошло на уровне СУБД:

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

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

Причина 2. Тяжелая конструкция В ИЕРАРХИИ внутри параметров виртуальной таблицы

Конструкция В ИЕРАРХИИ при выполнении запроса разворачивается платформой в рекурсивную выборку всех элементов-потомков и передачу их во внутренний запрос через массив IN (...). Если поместить такое условие в параметры виртуальной таблицы СрезПоследних, огромный массив значений встраивается внутрь каждого подзапроса группировки и расчета максимальной даты, что приводит к резкой деградации производительности.

Способы правильной оптимизации запроса

Разберем практические варианты ускорения в зависимости от поставленной задачи.

Вариант 1. Получение записей регистра за период (без среза)

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


ВЫБРАТЬ
    Виды.Ссылка КАК Вид
ПОМЕСТИТЬ ВТ_Виды
ИЗ
    Справочник.ВидыПланов КАК Виды
ГДЕ
    Виды.Ссылка В ИЕРАРХИИ(&ВыбВид)

ИНДЕКСИРОВАТЬ ПО
    Вид
;

ВЫБРАТЬ
    План.Клуб КАК Клуб,
    План.Вид КАК Вид,
    План.Сумма КАК Сумма,
    План.Период КАК Период
ИЗ
    РегистрСведений.План КАК План
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Виды КАК ВТ_Виды
        ПО План.Вид = ВТ_Виды.Вид
ГДЕ
    План.Период МЕЖДУ &ВыбНач И &ВыбКон
    И План.Клуб = &ВыбКлуб
ИТОГИ
    СУММА(Сумма)
ПО
    ОБЩИЕ

Вариант 2. Получение среза последних с фильтрацией по иерархии

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


ВЫБРАТЬ
    Виды.Ссылка КАК Вид
ПОМЕСТИТЬ ВТ_НужныеВиды
ИЗ
    Справочник.ВидыПланов КАК Виды
ГДЕ
    Виды.Ссылка В ИЕРАРХИИ(&ВыбВид)

ИНДЕКСИРОВАТЬ ПО
    Вид
;

ВЫБРАТЬ
    План.Клуб КАК Клуб,
    План.Вид КАК Вид,
    План.Сумма КАК Сумма,
    План.Период КАК Период
ИЗ
    РегистрСведений.План.СрезПоследних(&ВыбКон, Клуб = &Клуб) КАК План
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_НужныеВиды КАК ВТ_НужныеВиды
        ПО План.Вид = ВТ_НужныеВиды.Вид
ИТОГИ
    СУММА(Сумма)
ПО
    ОБЩИЕ

В этом случае в параметрах среза остаются только точные отборы на равенство по проиндексированным измерениям (Клуб = &Клуб), а тяжелое условие иерархии отрабатывает через эффективное внутреннее соединение с проиндексированной временной таблицей.

Особенности работы с регистрами накопления (Обороты)

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

  1. Точные границы периода: Даты начала и конца периода (&ВыбНач и &ВыбКон) должны строго соответствовать границам периодичности хранения итогов (например, начало первого дня месяца 00:00:00 и конец последнего дня 23:59:59). При произвольных секундах платформа будет дополнительно считывать физические таблицы движений.
  2. Порядок измерений: Первыми в структуре регистра метаданных конфигуратора должны располагаться те измерения, по которым чаще всего накладываются жесткие фильтры на точное равенство.
← На главную