Что быстрее в запросах 1С: фильтрация по типу через ССЫЛКА, ТИПЗНАЧЕНИЯ или В ИЕРАРХИИ

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

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

Метод 1: Использование оператора В ИЕРАРХИИ

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

Метод 2: ТИПЗНАЧЕНИЯ и ТИП

Конструкция ТИПЗНАЧЕНИЯ(Субконто1) = ТИП(Справочник.ФизическиеЛица) выглядит логично, но имеет свои нюансы. Разберем, как это работает «под капотом»:

В базе данных SQL составной тип (например, Субконто1) хранится в нескольких колонках. Обычно это идентификатор типа (_Subkonto1_TRef) и идентификатор ссылки (_Subkonto1_RRef). Когда мы используем ТИПЗНАЧЕНИЯ, платформа сравнивает значение в колонке _TRef.

Однако в старых версиях платформы или в сложных соединениях такая конструкция могла приводить к неявным соединениям с таблицами описания метаданных, что замедляло запрос. На современных версиях платформы 8.3 этот метод работает быстрее, чем В ИЕРАРХИИ, но все еще может уступать более специализированным операторам.

Метод 3: Оператор ССЫЛКА (наиболее предпочтительный)

Проанализируем использование ключевого слова ССЫЛКА. Пример кода:


ГДЕ
    Субконто1 ССЫЛКА Справочник.ФизическиеЛица

Это стандартный и очень эффективный способ. На уровне SQL он транслируется в максимально простую проверку одной колонки _TRef. Основные преимущества:

  1. SARGability: Условие является «поисковым» (SARGable), что позволяет SQL-серверу выполнять Index Seek (поиск по индексу), а не Index Scan (сканирование всего индекса).
  2. Лаконичность: Платформа сразу понимает намерение разработчика и не строит лишних планов выполнения.

Метод 4: ВЫРАЗИТЬ и проверка на NULL

Посмотрим на один из самых «хитрых» и быстрых способов, который часто применяют опытные разработчики для оптимизации виртуальных таблиц. Это использование функции ВЫРАЗИТЬ совместно с проверкой на NULL или пустую ссылку. Рассмотрим пример:


ВЫБРАТЬ
    Регистр.Субконто1,
    Регистр.СуммаОстаток
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(
        &Период,
        Счет = &Счет,
        ,
        ВЫРАЗИТЬ(Субконто1 КАК Справочник.ФизическиеЛица) <> ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка)
    ) КАК Регистр

Или еще более эффективный вариант для фильтрации именно по типу:


ГДЕ
    ВЫРАЗИТЬ(Субконто1 КАК Справочник.ФизическиеЛица) ЕСТЬ НЕ NULL

Выясним, почему это работает быстро. Когда вы применяете ВЫРАЗИТЬ в параметрах виртуальной таблицы, вы явно указываете платформе, к какой физической таблице справочника (через поле ссылки) нужно обращаться. Если тип Субконто1 не соответствует указанному, результат приведения будет NULL. Этот метод позволяет платформе максимально сузить выборку еще на этапе формирования исходного SQL-запроса к таблицам итогов.

Сравнительная таблица производительности

Проанализируем итоги и выстроим иерархию методов от самого быстрого к самому медленному:

  1. Место 1 (Лидер): ВЫРАЗИТЬ(... КАК ...) ЕСТЬ НЕ NULL или ССЫЛКА. Они работают напрямую с идентификаторами типов в индексах.
  2. Место 2: ТИПЗНАЧЕНИЯ(...) = ТИП(...). Работает хорошо, но менее универсально в плане оптимизации планов запросов.
  3. Место 3 (Аутсайдер): В ИЕРАРХИИ. Категорически не рекомендуется использовать для проверки типов из-за огромных накладных расходов.

Архитектурный совет по оптимизации

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

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

← На главную