Как оптимизировать запрос к регистру бухгалтерии при получении данных субконто?

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

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

Анализ исходной проблемы

Рассмотрим типичный запрос к виртуальной таблице ДвиженияССубконто, который стал причиной низкой производительности. Проблема заключается в обращении через точку к полям субконто, таким как ЕдиницаИзмерения:


ВЫБРАТЬ
    Хозрасчетный.СубконтоКт1 КАК Номенклатура,
    Хозрасчетный.СубконтоКт1.ЕдиницаИзмерения КАК ЕдИзм,
    ЕСТЬNULL(Хозрасчетный.КоличествоКт, 0) КАК Количество,
    Хозрасчетный.НомерСтроки КАК НомерСтроки,
    ЕСТЬNULL(Хозрасчетный.Сумма, 0) КАК Сумма
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Регистратор В(&МассивСсылка)
УПОРЯДОЧИТЬ ПО
    НомерСтроки

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

Решение 1: Использование оператора ВЫРАЗИТЬ

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

Рассмотрим, как изменится код:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Хозрасчетный.СубконтоКт1 КАК Справочник.Номенклатура) КАК Номенклатура,
    ВЫРАЗИТЬ(Хозрасчетный.СубконтоКт1 КАК Справочник.Номенклатура).ЕдиницаИзмерения КАК ЕдИзм,
    ...

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

Решение 2: Переход к физическим таблицам регистра

Виртуальная таблица ДвиженияССубконто — очень мощный, но крайне ресурсозатратный инструмент. Она динамически собирает данные из основной таблицы проводок и таблицы значений субконто. Если ваша задача ограничена выборкой по конкретным документам (регистраторам), эффективнее обратиться напрямую к физическим таблицам.

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


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

Такой подход исключает накладные расходы на работу виртуальной таблицы и позволяет СУБД построить более оптимальный план запроса.

Решение 3: Оптимизация работы с фильтром по Регистратору

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

Разберем по шагам правильный алгоритм действий:

  1. Использование временных таблиц: Поместите массив ссылок во временную таблицу. Это позволит оптимизатору запросов SQL лучше планировать соединения.
  2. Ограничение по счету: Обязательно добавляйте условие по счету (Счет = &НужныйСчет). Поле Счет входит в состав кластерного индекса, и его использование в условии ГДЕ дает колоссальный прирост скорости.
  3. Разделение запроса на пакеты: Сначала выберите только ссылки на номенклатуру из регистра во временную таблицу, а вторым запросом в пакете присоедините к ней необходимые реквизиты (единицы измерения, артикулы) напрямую из справочника.

Посмотрим на пример реализации с временной таблицей:


// Пакет 1: Помещаем ссылки во временную таблицу
ВЫБРАТЬ Ссылка ВТ_Документы ИЗ &МассивСсылка КАК Ссылка;

// Пакет 2: Выбираем данные из физической таблицы регистра
ВЫБРАТЬ
    Хозрасчетный.Регистратор,
    Хозрасчетный.НомерСтроки,
    Хозрасчетный.КоличествоКт,
    Хозрасчетный.Сумма,
    Хозрасчетный.Субконто1 КАК НоменклатураСсылка
ПОМЕСТИТЬ ВТ_ДанныеРегистра
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Регистратор В (ВЫБРАТЬ Ссылка ИЗ ВТ_Документы)
    И Хозрасчетный.Счет = &Счет41;

// Пакет 3: Соединяем со справочником для получения реквизитов
ВЫБРАТЬ
    ВТ.НоменклатураСсылка КАК Номенклатура,
    Номенклатура.ЕдиницаИзмерения КАК ЕдИзм,
    ВТ.КоличествоКт,
    ВТ.Сумма
ИЗ
    ВТ_ДанныеРегистра КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ
    Справочник.Номенклатура КАК Номенклатура
ПО
    ВТ.НоменклатураСсылка = Номенклатура.Ссылка

Дополнительные советы по производительности

Проанализируем еще несколько важных моментов:

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

← На главную