К статье
Практический материал

Разработка и Конфигурация · 11 мин

Временная таблица в 1С: для чего нужна и как её использовать

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

Временная таблица в 1С — это промежуточный набор данных, который создаётся внутри пакетного запроса и существует только во время его выполнения. Она позволяет разбить сложную выборку на понятные этапы: сначала отобрать и подготовить часть данных, затем использовать результат в следующих запросах пакета. Без временных таблиц многие задачи пришлось бы решать громоздкими вложенными запросами или многократными обходами результата в коде.

Механизм встроен в язык запросов 1С: разработчик пишет конструкцию ПОМЕСТИТЬ ИмяТаблицы, а платформа складывает результат в оперативную память или во временное хранилище СУБД. К этой таблице можно обращаться в последующих запросах пакета как к обычному источнику данных — соединять, фильтровать, группировать.

Тема важна не только для оптимизации. Временные таблицы делают код читаемым: вместо одного запроса на несколько экранов с тремя уровнями вложенности вы получаете последовательность логичных шагов, каждый из которых легко проверить в консоли запросов. Ниже разобраны сценарии применения, синтаксис, работа с менеджером временных таблиц и типичные ошибки.

Что такое временная таблица и где она живёт

Физически временная таблица — это набор строк, созданный платформой по результату исполнения запроса с предложением ПОМЕСТИТЬ. В файловом варианте базы данные размещаются в оперативной памяти сервера или рабочего процесса, в клиент-серверном — во временных таблицах СУБД (например, в tempdb у MS SQL Server). Разработчику не нужно управлять размещением вручную: платформа делает это автоматически.

Время жизни таблицы ограничено. Если она создана внутри пакетного запроса без явного менеджера, она доступна до конца выполнения пакета. Если запросу назначен объект МенеджерВременныхТаблиц, таблица живёт, пока жив этот менеджер, и её можно использовать в нескольких отдельных запросах. После уничтожения менеджера или выполнения команды УНИЧТОЖИТЬ данные удаляются.

Для чего нужны временные таблицы: основные сценарии

Главная цель — декомпозиция сложной логики. Когда отчёт должен сначала отобрать документы по условиям, потом рассчитать обороты, затем свернуть результат по контрагентам, каждый шаг естественно оформить отдельным запросом с помещением во временную таблицу. Итоговый запрос работает уже с подготовленными данными, а не с полными таблицами базы.

Вторая частая задача — многократное использование одного и того же отбора. Если пять запросов пакета опираются на список «активных номенклатурных позиций», выгоднее один раз поместить этот список во временную таблицу и соединяться с ней, чем пять раз повторять сложный подзапрос. Это и читаемее, и быстрее.

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

Повторный отборОдин подзапрос используется 2+ раза

Поместите его в ВТ один раз и соединяйтесь с ней

Сложная логикаЗапрос не читается из-за вложенности

Разбейте на этапы через ПОМЕСТИТЬ

Данные из кодаНужно передать таблицу значений в запрос

Передайте параметром и поместите в ВТ

Одноразовый фильтрПростое условие по одному полю

ВТ не нужна — достаточно ГДЕ

Синтаксис: как создать временную таблицу

Создание выполняется добавлением предложения ПОМЕСТИТЬ ИмяТаблицы после секции выборки полей и перед предложением ИЗ — точное положение определяет синтаксис языка запросов: конструкция идёт сразу после списка полей. Пример:

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

СУММА(Продажи.Количество) КАК Количество

ПОМЕСТИТЬ ВТ_Продажи

ИЗ

РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи

СГРУППИРОВАТЬ ПО

Продажи.Номенклатура

;

ВЫБРАТЬ

ВТ.Номенклатура,

ВТ.Количество,

Спр.Артикул

ИЗ

ВТ_Продажи КАК ВТ

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Спр

ПО ВТ.Номенклатура = Спр.Ссылка

Имена временных таблиц должны быть уникальны в рамках пакета и менеджера. Принято давать им префикс ВТ_, чтобы при чтении запроса сразу было видно, откуда берутся данные. Обращение к таблице в дальнейших запросах ничем не отличается от обращения к обычной таблице базы.

Если временная таблица больше не нужна до конца пакета, её стоит явно удалить командой УНИЧТОЖИТЬ ВТ_Продажи. Это освобождает память и снижает нагрузку на СУБД, особенно когда таблица крупная, а пакет длинный.

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

Менеджер временных таблиц: передача данных между запросами

Объект МенеджерВременныхТаблиц нужен, когда временные таблицы должны пережить один запрос и использоваться в следующих. Вы создаёте менеджер, присваиваете его свойству МенеджерВременныхТаблиц каждого запроса — и все они видят одни и те же таблицы.

Типовой приём — передать таблицу значений из кода. Таблица значений передаётся параметром, а первый запрос помещает её во временную таблицу:

ВЫБРАТЬ

Список.Номенклатура КАК Номенклатура,

Список.Цена КАК Цена

ПОМЕСТИТЬ ВТ_Список

ИЗ

&ТаблицаЗначений КАК Список

Важное ограничение: поля таблицы значений, передаваемой параметром, должны иметь типы, которые можно выразить в запросе. Колонки с составными или неопределёнными типами могут вызвать ошибку, поэтому таблицу значений перед передачей стоит явно типизировать через Новый ОписаниеТипов.

Порядок работы с менеджером временных таблиц
  1. 1
    Создайте объект МенеджерВременныхТаблиц
  2. 2
    Назначьте его каждому запросу, который должен видеть общие таблицы
  3. 3
    Выполните запрос с ПОМЕСТИТЬ — таблица сохранится в менеджере
  4. 4
    Выполните следующие запросы, обращаясь к таблице по имени
  5. 5
    После завершения выполните УНИЧТОЖИТЬ или дайте менеджеру выйти из области видимости

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

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

Однако временная таблица — не универсальное ускорение. Если в неё помещается очень большой объём данных «на всякий случай», а используется из него малая часть, вы получаете лишнюю запись и чтение миллионов строк. Правило: помещайте во временную таблицу только те поля и строки, которые реально нужны дальше, и накладывайте отборы как можно раньше.

Ещё один фактор — виртуальные таблицы регистров. Обращение к виртуальной таблице Остатки или Обороты с параметрами периода само по себе эффективно; оборачивать его во временную таблицу стоит только когда результат используется многократно или требует дополнительной обработки.

Типичные ошибки при работе с временными таблицами

Самая распространённая ошибка — обращение к временной таблице, которая уже не существует. Это происходит, когда запрос выполняется без менеджера, а таблица была создана другим запросом, либо когда таблица удалена командой УНИЧТОЖИТЬ раньше времени. Платформа выдаёт ошибку «Таблица не найдена».

Вторая группа ошибок связана с дублированием имён: попытка поместить таблицу с именем, которое уже занято в пакете или менеджере. Платформа не перезаписывает таблицу молча — возникает ошибка, поэтому при динамической сборке текста запроса следите за уникальностью имён.

Третья частая проблема — потеря производительности из-за соединения с временной таблицей без индекса по полям соединения. Если соединение работает медленно, проверьте, не сканируется ли таблица целиком, и рассмотрите вариант сокращения её состава до нужных полей.

Типичные ошибки
01
Обращение к ВТ из запроса без общего менеджера — ошибка «Таблица не найдена»
02
Помещение в ВТ всех полей и строк без отбора — перерасход памяти и tempdb
03
Дублирование имён таблиц в пакете — ошибка выполнения запроса
04
Забытый УНИЧТОЖИТЬ в длинном пакете — таблицы копятся и тормозят последующие запросы
05
Передача таблицы значений с нетипизированными колонками — ошибка типа параметра

Как проверить и отладить запрос с временными таблицами

Основной инструмент — консоль запросов: она позволяет выполнить пакет по шагам и посмотреть содержимое каждой временной таблицы. В управляемом приложении удобно выводить промежуточный результат через Запрос.Выполнить().Выгрузить() и проверять число строк и значения ключевых полей.

Для анализа производительности используйте технологический журнал и план запроса на стороне СУБД. Признак проблемы — длительное выполнение именно запроса с ПОМЕСТИТЬ или массовые операции записи в tempdb. В таком случае сокращайте состав выборки и переносите условия в параметры виртуальных таблиц.

Контрольные точки

Как проверить результат

Содержимое ВТ после ПОМЕСТИТЬ
Норма

Строки и поля соответствуют ожидаемому отбору

Тревожный признак

Пусто, дубли или лишние строки — проверьте условия и группировку

Время выполнения пакета
Норма

Растёт умеренно при добавлении ВТ

Тревожный признак

Резкий рост — ВТ слишком велика или нет индекса соединения

Повторное использование
Норма

Все запросы видят таблицу через общий менеджер

Тревожный признак

Ошибка «Таблица не найдена» — менеджер не назначен

FAQ: частые вопросы о временных таблицах в 1С

Чем временная таблица отличается от вложенного запроса?

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

Можно ли использовать временную таблицу в другом запросе после Выполнить()?

Да, если обоим запросам назначен один и тот же объект МенеджерВременныхТаблиц. Без менеджера таблица существует только внутри пакетного запроса, в котором создана, и недоступна извне.

Нужно ли удалять временные таблицы вручную?

В коротком пакете платформа удалит их автоматически. В длинных пакетах и при работе через менеджер явная команда УНИЧТОЖИТЬ освобождает память и ресурсы СУБД сразу после того, как таблица перестала быть нужна, что полезно на крупных выборках.

Как передать список значений из кода в запрос?

Сформируйте таблицу значений с типизированными колонками, передайте её параметром запроса и в первом запросе пакета поместите во временную таблицу через конструкцию ИЗ &ИмяПараметра. Дальше соединяйте эту таблицу с данными базы.

Почему запрос с временной таблицей стал работать медленнее?

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

Работают ли временные таблицы в СКД?

Да, набор данных «Запрос» в схеме компоновки данных поддерживает пакетные запросы с ПОМЕСТИТЬ. Это стандартный способ подготовить данные для отчёта: промежуточные таблицы строятся при формировании, а в результирующую выборку попадает только финальный запрос пакета.

Итог

Что важно запомнить

Временная таблица в 1С создаётся конструкцией ПОМЕСТИТЬ и служит для поэтапной обработки данных, повторного использования отборов и передачи таблиц значений в запрос. Помещайте в неё только нужные строки и поля, используйте общий менеджер для связки запросов и удаляйте крупные таблицы командой УНИЧТОЖИТЬ.