Для чего создается временная таблица при выборке остатков и оборотов из регистра накопления?

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

При анализе чужого кода или разработке собственных сложных отчетов в системе 1С:Предприятие программисты часто сталкиваются с конструкцией, когда данные из виртуальной таблицы ОстаткиИОбороты сначала помещаются во временную таблицу, и только вторым запросом из этой временной таблицы выбираются нужные поля с применением условий ВЫБОР или группировок. На первый взгляд это кажется избыточным: зачем плодить лишние сущности в tempdb, если можно написать один «плоский» запрос? Разберем по шагам, почему такой подход является не просто «хорошим тоном», а технической необходимостью для обеспечения стабильной производительности системы.

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

Рассмотрим типовой пример запроса, который вызывает вопросы у начинающих разработчиков. Проанализируем ситуацию: данные из регистра накопления УПЖКХ_ДанныеДляОтраженияНачисленийВРеглУчете выбираются за определенный период и помещаются во временную таблицу ВрТаблицаОстатковИОборотов без каких-либо дополнительных вычислений. Затем во втором запросе пакета к этой временной таблице применяются конструкции ВЫБОР КОГДА ... ТОГДА для распределения сумм по колонкам в зависимости от раздела учета.

Проанализируем пример кода:


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВрТаблица.Организация,
    ВЫБОР
        КОГДА ВрТаблица.РазделУчета = ЗНАЧЕНИЕ(Перечисление.УПЖКХ_РазделыУчета.Льготы)
            ТОГДА ВрТаблица.СуммаПриход
        ИНАЧЕ 0
    КОНЕЦ КАК СуммаПриходЛьготы
ИЗ
    ВрТаблица КАК ВрТаблица;

Выясним причину такого разделения. Основной вопрос: почему нельзя использовать ВЫБОР сразу в первом запросе? Ответ кроется в особенностях работы СУБД и механизмах трансляции запросов платформой 1С.

1. Помощь оптимизатору СУБД (SQL Optimizer)

Виртуальная таблица ОстаткиИОбороты не существует в базе данных физически. В момент выполнения запроса платформа 1С трансформирует ее в огромный и сложный SQL-запрос. Этот запрос может включать в себя соединения таблиц итогов (остатков), таблиц оборотов и иногда даже таблицы движений (если итоги не рассчитаны или период не кратен месяцу). Для SQL-сервера такая виртуальная таблица является «черным ящиком» с неопределенным количеством строк.

Когда мы добавляем сложные условия ВЫБОР или дополнительные соединения прямо в запрос к виртуальной таблице, оптимизатор СУБД (особенно в MS SQL Server) часто ошибается в расчете стоимости плана запроса. Он может решить, что данных будет мало, и выберет неэффективный алгоритм (например, Nested Loops вместо Hash Join), что приведет к катастрофическому падению скорости на больших объемах данных.

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

2. Снижение времени блокировок и нагрузки на итоги

Запросы к таблицам итогов регистров накопления являются ресурсоемкими. Проанализируем ситуацию с точки зрения многопользовательской работы: чем дольше выполняется запрос, обращающийся к физическим таблицам регистра, тем дольше удерживаются ресурсы (S-блокировки в режиме Read Committed или нагрузка на дисковую подсистему).

Используя временную таблицу, мы максимально быстро «выкачиваем» сырые данные из регистра и закрываем обращение к основным таблицам БД. Вся последующая «тяжелая» логика — вычисления через ВЫБОР, агрегация, группировка — происходит уже над данными в tempdb. Это значительно повышает общую параллельность работы системы, так как основные таблицы освобождаются быстрее.

3. Особенности трансляции условий в SQL-код

Рассмотрим, как платформа 1С транслирует наши условия. Если прописать ВЫБОР внутри обращения к ОстаткиИОбороты, платформа может попытаться «пробросить» эту логику максимально глубоко в подзапросы SQL. В некоторых случаях это приводит к тому, что вычисления CASE (аналог ВЫБОР в SQL) будут производиться для каждой строки движений регистра до того, как они будут свернуты в итоги.

Разберем, к чему это ведет:

  1. Увеличивается нагрузка на процессор сервера БД.
  2. Если данных в движениях миллионы, а в итогах тысячи — разница в скорости будет колоссальной.

Вынося ВЫБОР во второй запрос, мы гарантируем, что вычисления затронут только уже отобранные и свернутые данные.

4. Использование индексов и статистики

Одним из важнейших преимуществ временных таблиц является возможность создания индексов. Хотя в приведенном автором примере индексация не используется, сам подход подготавливает почву для оптимизации. Если бы нам потребовалось соединить результат ОстаткиИОбороты с другой таблицей (например, со справочником ЛицевыеСчета), создание индекса по полю ЛицевойСчет во временной таблице стало бы ключом к быстрому выполнению запроса.

Кроме того, платформа 1С при использовании временных таблиц может инициировать перекомпиляцию последующих запросов пакета. Это позволяет SQL-серверу учитывать свежую статистику распределения данных именно для вашего периода и фильтров. Это решает известную проблему Parameter Sniffing, когда один и тот же запрос летает за секунду при малом периоде и «вешает» базу при выборке за год.

5. Особенности работы с PostgreSQL

Если ваша информационная база работает на СУБД PostgreSQL, использование временных таблиц становится критически важным. Планировщик Postgres зачастую не справляется с глубоко вложенными подзапросами, которыми являются виртуальные таблицы 1С. Явная материализация данных во временную таблицу в Postgres часто дает кратный (в 10 и более раз) прирост скорости по сравнению с «одним большим запросом».

6. Принцип единственной ответственности в запросах

С точки зрения чистоты кода и архитектуры, разделение запроса на этапы делает его более читаемым и поддерживаемым.

  1. Первый этап: Извлечение данных из источника (физических или виртуальных таблиц) с минимальными фильтрами.
  2. Второй этап: Преобразование данных, расчеты, приведение типов, группировка.

Это позволяет легко вносить изменения. Например, если завтра потребуется изменить логику расчета полей СуммаПриходЛьготы, вам не придется трогать сложный запрос к регистру — вы измените только логику обработки во второй части пакета.

Резюме

Использование временной таблицы для данных виртуальной таблицы ОстаткиИОбороты — это не «мода» и не «избыточность». Это осознанный защитный механизм, который:

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

← На главную