Какой метод в запросе выбрать: МенеджерВременныхТаблиц или ВыполнитьПакетСПромежуточнымиДанными?

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

При разработке сложных запросов в системе 1С:Предприятие 8 программисты часто сталкиваются с необходимостью не просто получить финальный результат, но и проанализировать или использовать данные, которые были помещены во временные таблицы (ВТ) в процессе выполнения пакета. Исторически для этого использовался МенеджерВременныхТаблиц, однако с выходом платформы версии 8.3.10 появился альтернативный метод — ВыполнитьПакетСПромежуточнымиДанными. Разберем детально, в чем разница между этими подходами, какой из них эффективнее и в каких ситуациях стоит отдать предпочтение конкретному инструменту.

Метод 1: Использование Менеджера временных таблиц (МВТ)

Рассмотрим классический способ. МенеджерВременныхТаблиц — это объект, который служит контейнером для хранения временных таблиц в сеансе работы с базой данных. Он позволяет "выносить" таблицы за рамки одного запроса и использовать их в последующих обращениях к СУБД. Проанализируем типичный пример кода для этого метода:


МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст = 
    "ВЫБРАТЬ Ссылка ПОМЕСТИТЬ ВТ_Товары ИЗ Справочник.Номенклатура;
    |ВЫБРАТЬ Ссылка ПОМЕСТИТЬ ВТ_Склады ИЗ Справочник.Склады;
    |ВЫБРАТЬ * ИЗ ВТ_Товары";

РезультатЗапроса = Запрос.Выполнить();

// Получаем данные конкретной таблицы по её индексу в менеджере
ТаблицаТовары = Запрос.МенеджерВременныхТаблиц.Таблицы[0].ПолучитьДанные().Выгрузить();
ТаблицаСклады = Запрос.МенеджерВременныхТаблиц.Таблицы[1].ПолучитьДанные().Выгрузить();

Особенности этого способа:

  1. Жизненный цикл: Временные таблицы живут столько, сколько живет объект МенеджерВременныхТаблиц. Мы можем передать этот менеджер в другую процедуру или даже в другой запрос, и таблицы будут доступны.
  2. Ленивая загрузка: Данные из SQL-сервера не передаются в память 1С автоматически. Они "лежат" в TempDB на сервере базы данных до тех пор, пока мы явно не вызовем метод ПолучитьДанные().Выгрузить().
  3. Управление ресурсами: Если мы уничтожим таблицу внутри запроса командой УНИЧТОЖИТЬ, она полностью исчезнет из коллекции Таблицы менеджера.

Метод 2: ВыполнитьПакетСПромежуточнымиДанными

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ Ссылка ПОМЕСТИТЬ ВТ_Товары ИЗ Справочник.Номенклатура;
    |ВЫБРАТЬ Ссылка ПОМЕСТИТЬ ВТ_Склады ИЗ Справочник.Склады;
    |ВЫБРАТЬ * ИЗ ВТ_Товары";

РезультатыПакета = Запрос.ВыполнитьПакетСПромежуточнымиДанными();

// Данные каждой таблицы доступны как элементы массива
ТаблицаТовары = РезультатыПакета[0].Выгрузить();
ТаблицаСклады = РезультатыПакета[1].Выгрузить();
ИтоговыйРезультат = РезультатыПакета[2].Выгрузить();

Особенности этого способа:

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

Сравнительный анализ и выбор оптимального решения

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

Потребление памяти (Жадность vs Экономность):
Метод ВыполнитьПакетСПромежуточнымиДанными является "жадным". Если ваш запрос создает временные таблицы объемом в миллионы строк, вызов этого метода приведет к попытке загрузить все эти миллионы строк в память сервера приложений 1С. Это может вызвать критическую нехватку памяти (Out of Memory).
В то же время МенеджерВременныхТаблиц позволяет выгрузить только ту таблицу, которая действительно нужна для постобработки в коде, оставляя остальные в TempDB на SQL-сервере.

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

Удобство отладки и анализа:
Для быстрой отладки или написания инструментов типа "Консоль запросов" метод ВыполнитьПакетСПромежуточнымиДанными неоспоримо удобнее. Нам не нужно инициализировать менеджер, связывать его с запросом и обращаться к свойствам коллекции. Мы получаем один массив, где прозрачно видны все этапы преобразования данных.

Работа с Системой компоновки данных (СКД):
Рассмотрим ситуацию, когда запрос подготавливает данные для СКД. СКД умеет работать с объектом МенеджерВременныхТаблиц, принимая его как внешний источник. С массивом результатов, полученным вторым методом, интегрировать СКД будет гораздо сложнее (придется передавать данные как внешние наборы данных типа "Таблица значений").

Рекомендации по использованию

Проанализировав оба подхода, мы можем сформулировать следующие правила выбора:

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

Используйте ВыполнитьПакетСПромежуточнымиДанными, если:

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

← На главную