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

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

Часто при разработке регламентных заданий или обработок по очистке базы данных (например, в конфигурации 1С:Бухгалтерия 3.0) мы сталкиваемся с необходимостью найти записи в регистрах, где в качестве аналитики указаны объекты, помеченные на удаление. Разберем конкретную и очень интересную задачу: как максимально быстро и без перегрузки сервера найти остатки по счету, если одно из субконто (справочник) помечено на удаление.

Проанализируем ситуацию: поле субконто имеет составной тип данных. Обычный подход «в лоб» здесь работает крайне медленно или вообще приводит к аварийному завершению работы СУБД. Рассмотрим подробнее причины такого поведения и по шагам выработаем самое оптимальное решение.

Почему база "вылетает" при простых запросах?

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

Выясним причину: когда платформа 1С транслирует такой запрос в SQL, происходит неявное соединение (разыменование ссылок). Так как поле субконто содержит составной тип (множество справочников и документов), СУБД попытается соединить гигантскую таблицу итогов регистра бухгалтерии со всеми физическими таблицами объектов, которые входят в этот тип данных. План запроса разрастается до огромных размеров, сервер баз данных исчерпывает доступную оперативную память, и база «вылетает».

Разберем неоптимальные варианты написания запроса

Чтобы понять, как делать правильно, проанализируем несколько популярных подходов и результаты замеров их производительности.

  1. Условие в секции ГДЕ без типизации. Если мы напишем условие ГДЕ ХозрасчетныйОстатки.Субконто1.ПометкаУдаления, запрос выполнится, но займет очень много времени (в нашем примере — около 24 секунд). Это классический антипаттерн 1С. СУБД сначала рассчитает и получит все остатки по счетам без фильтра, и только потом начнет отбрасывать лишние строки. Это приводит к колоссальному избыточному чтению данных.

  2. Типизация через ВЫРАЗИТЬ в параметрах виртуальной таблицы. Использование конструкции ВЫРАЗИТЬ(Субконто1 КАК Справочник.ИмяСправочника).ПометкаУдаления внутри параметров виртуальной таблицы решает проблему падения базы, так как мы ограничиваем неявное соединение одной конкретной таблицей. Время выполнения снижается до ~2.4 секунд. Это рабочий вариант, но его можно улучшить.

Рассмотрим оптимальный алгоритм решения

Правильная архитектурная мысль заключается в том, чтобы вообще избавиться от разыменования полей (обращения через точку) при работе с огромными таблицами итогов. Для этого соберем нужные нам данные заранее.

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

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

Посмотрим на пример оптимального запроса, который отрабатывает всего за ~1.5 секунды:


ВЫБРАТЬ
    ТекСправочник.Ссылка КАК Ссылка
ПОМЕСТИТЬ втИмяСправочника
ИЗ
    Справочник.ИмяСправочника КАК ТекСправочник
ГДЕ
    ТекСправочник.ПометкаУдаления

ИНДЕКСИРОВАТЬ ПО
    Ссылка
;

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

Проанализируем важные детали оптимального запроса

Обратите внимание на использование параметра &ВидСубконтоИмяСправочника. Это не просто декорация для упорядочивания колонок субконто (чтобы точно знать, что Субконто1 — это именно нужный справочник). В платформе 1С итоги регистра бухгалтерии физически хранятся в нескольких разных таблицах баз данных, которые зависят от количества и видов привязанных к счету субконто.

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

Условие В (ВЫБРАТЬ...) внутри параметров виртуальной таблицы на уровне СУБД преобразуется во внутреннее соединение (INNER JOIN) с нашей проиндексированной временной таблицей. Так как индекс уже построен, соединение происходит мгновенно.

Альтернативный вариант: использование массивов во встроенном языке

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

Мы можем сформировать массив ссылок на помеченные на удаление элементы (например, используя функцию НайтиПомеченныеНаУдаление() или отдельным легким запросом), а затем просто передать этот массив в параметры виртуальной таблицы регистра:


// Фрагмент условия внутри виртуальной таблицы:
И Субконто1 В (&МассивПомеченныхНаУдаление)

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

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

← На главную