Как получить текст запроса для заполнения временной таблицы в 1С:Предприятие 8

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

Бесплатная консультация юриста

+7 (800) 302-87-29

Реклама jurik.ru

В современных конфигурациях на платформе 1С:Предприятие 8 эффективная работа с большими объемами данных немыслима без грамотного использования временных таблиц․ Класс МенеджерВременныхТаблиц (TemporaryTablesManager) является ключевым инструментом для управления жизненным циклом этих таблиц․ В данной статье подробно разберем‚ как получить текст запроса‚ заполняющего временную таблицу‚ а также рассмотрим лучшие практики работы с этим механизмом․

Архитектура и назначение Менеджера временных таблиц

Временные таблицы в 1С создаются в tempdb СУБД (MS SQL Server‚ PostgreSQL‚ Oracle‚ IBM DB2) и существуют только в рамках текущего сеанса или транзакции․ Это позволяет:

  • Снизить нагрузку на основные таблицы базы данных․
  • Избежать блокировок при сложных расчетах и отчетах․
  • Оптимизировать планы запросов‚ разбивая сложную логику на этапы (materialization)․

Объект МенеджерВременныхТаблиц предоставляет методы для:

  1. Создания и удаления временных таблиц․
  2. Управления индексами и статистикой․
  3. Контроля параметров таблиц (уникальность‚ время жизни)․
Важно: Временные таблицы менеджера, это не таблицы значений (объект ТаблицаЗначений)‚ которые хранятся в оперативной памяти клиента/сервера․ Это физические таблицы в СУБД‚ доступ к которым осуществляется через язык запросов․

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

Сам по себе объект МенеджерВременныхТаблиц не хранит тексты запросов‚ которые использовались для заполнения таблиц․ Он управляет только структурой (метаданными) таблиц․ Текст запроса формируется разработчиком в коде и передается в метод Выполнить объекта Запрос․

Стандартный паттерн: Запись данных во временную таблицу

Классическая схема выглядит следующим образом:

// 1․ Получаем менеджер
МенеджерВТ = Новый МенеджерВременныхТаблиц;

// 2․ Описываем структуру таблицы (или используем автоматическое создание по полям запроса)
// Рекомендуется явно задавать структуру для контроля типов и индексов
ОписаниеТЧ = Новый ОписаниеВременнойТаблицы;
ОписаниеТЧ․Колонки․Добавить("Номенклатура"‚ Новый ОписаниеТипов("СправочникСсылка․Номенклатура"));
ОписаниеТЧ․Колонки․Добавить("Количество"‚ Новый ОписаниеТипов("Число"‚ 15‚ 3));
ОписаниеТЧ․Индексы․Добавить("Номенклатура"); // Создаем индекс сразу

// 3․ Создаем таблицу в СУБД
ИмяВТ = МенеджерВТ․СоздатьВременнуюТаблицу(ОписаниеТЧ); // Возвращает имя таблицы (например‚ #tt123)

// 4․ Формируем ТЕКСТ ЗАПРОСА (Вот он — то‚ что вы ищете)
ТекстЗапроса = "
|ВЫБРАТЬ
| ТоварыНаСкладах․Номенклатура КАК Номенклатура‚
| СУММА(ТоварыНаСкладах․Количество) КАК Количество
|ПОМЕСТИТЬ " + ИмяВТ + "
|ИЗ
| РегистрНакопления;ТоварыНаСкладах КАК ТоварыНаСкладах
|ГДЕ
| ТоварыНаСкладах․Склад = &Склад
|СГРУППИРОВАТЬ ПО
| ТоварыНаСкладах․Номенклатура
|;";

// 5․ Выполняем запрос
Запрос = Новый Запрос(ТекстЗапроса);
Запрос․УстановитьПараметр("Склад"‚ Склад);
Запрос․Выполнить; // Данные попадают во временную таблицу в СУБД

Как «получить» запрос программно (Динамическое формирование)

Если задача стоит сгенерировать текст запроса динамически (например‚ в универсальных отчетах или конструкторах)‚ используйте объект СхемаКомпоновкиДанных (СКД) или строковые шаблоны․

Пример: Функция генерации запроса заполнения ВТ

Функция ПолучитьТекстЗапросаЗаполненияВТ(ИмяВТ‚ ПараметрыФильтра) Экспорт
 
 СтрокаЗапроса = Новый СтроковыйОбъект;
  СтрокаЗапроса․ДобавитьСтроку("ВЫБРАТЬ");
 СтрокаЗапроса․ДобавитьСтроку(" Продажи․Номенклатура‚");
 СтрокаЗапроса․ДобавитьСтроку(" СУММА(Продажи․Сумма) КАК СуммаПродаж");
 СтрокаЗапроса․ДобавитьСтроку("ПОМЕСТИТЬ " + ИмяВТ);
 СтрокаЗапроса․ДобавитьСтроку("ИЗ");
 СтрокаЗапроса․ДобавитьСтроку(" Документ․РеализацияТоваровУслуг КАК Продажи");
 СтрокаЗапроса․ДобавитьСтроку("ГДЕ");
 СтрокаЗапроса․ДобавитьСтроку(" Продажи․Дата МЕЖДУ &НачалоПериода И &КонецПериода");
 
 // Динамическое добавление условий
 Если ПараметрыФильтра․Свойство("Номенклатура"‚ ВременнаяТаблица) Тогда
 СтрокаЗапроса․ДобавитьСтроку(" И Продажи․Номенклатура В &СписокНоменклатуры");
 КонецЕсли;
 
 СтрокаЗапроса․ДобавитьСтроку("СГРУППИРОВАТЬ ПО");
 СтрокаЗапроса․ДобавитьСтроку(" Продажи․Номенклатура");
 
 Возврат СтрокаЗапроса․ПолучитьСтроку;
 
КонецФункции

Продвинутые техники: Пакетное выполнение и BatchSeparators

Начиная с платформы 8․3․18+‚ для массовой загрузки данных во временные таблицы (особенно актуально для PostgreSQL и MS SQL) рекомендуется использовать пакетное выполнение запросов через разделитель пакетов (`;` в конце запроса + метод `ВыполнитьПакет` или настройку `BatchSize`)․

Это критически важно для производительности при загрузке миллионов записей (как упоминалось в актуальных обновлениях платформы: загрузка 1 млн записей XLSX за 53 сек)․

Пример пакетной вставки:

Запрос․Текст = 
"ВЫБРАТЬ * ПОМЕСТИТЬ #ttData ИЗ &ТаблицаЗначений; // Пакет 1
|
|СОЗДАТЬ ИНДЕКС idx_Номенклатура ON #ttData (Номенклатура); // Пакет 2 (DDL)
|
|ОБНОВИТЬ СТАТИСТИКУ #ttData; // Пакет 3 (Статистика для планировщика)";

// Установка параметра таблицы значений
Запрос․УстановитьПараметр("ТаблицаЗначений"‚ ТЗДанных);
// Выполнение пакета
Результат = Запрос․ВыполнитьПакет; 

Управление статистикой и планами запросов (PostgreSQL / MS SQL)

Планировщик запросов СУБД (особенно PostgreSQL) часто строит неоптимальные планы для временных таблиц из-за отсутствия статистики․ Менеджер временных таблиц позволяет это исправить․

Обновление статистики вручную

После заполнения большой временной таблицы обязательно обновляйте статистику:

// Для PostgreSQL
МенеджерВТ․ОбновитьСтатистику(ИмяВТ); // Вызывает ANALYZE

// Для MS SQL Server платформа делает это автоматически при создании индексов‚
// но явный вызов sp_updatestats иногда полезен через прямой SQL․

Принудительное создание индексов

Не полагайтесь на автоиндексы․ Явно объявляйте их в ОписаниеВременнойТаблицы:

ОписаниеТЧ․Индексы․Добавить("Номенклатура‚ Склад"); // Составной индекс
ОписаниеТЧ․Индексы․Добавить("Период"); // Индекс для диапазонных выборок

Диагностика: Как посмотреть‚ что происходит в СУБД

Поскольку текст запроса формируется в коде 1С‚ а выполняется на сервере БД‚ для отладки используйте:

  • Технологический журнал (ТЖ): События `DBPOSTGRS`‚ `DBMSSQL`‚ `EXCP` — покажут реальный SQL‚ ушедший на сервер․
  • Консоль запросов (в конфигураторе): Позволяет выполнить текст запроса с параметрами и посмотреть план (Explain Analyze)․
  • Просмотр системных представлений СУБД: `pg_stat_user_tables` (Postgres)‚ `tempdb․sys․dm_db_index_usage_stats` (MS SQL)․

Типичные ошибки и лучшие практики (Best Practices)

Ошибка Последствие Решение
Неявное создание таблицы (без ОписаниеВременнойТаблицы) Типы полей определяются по первому ряду‚ нет индексов‚ плохие планы запросов․ Всегда используйте ОписаниеВременнойТаблицы с явными типами и индексами․
Игнорирование обновления статистики Планировщик думает‚ что таблица пустая (1 строка)‚ выбирает Nested Loops вместо Hash Join․ Вызывайте МенеджерВТ․ОбновитьСтатистику после массовой загрузки․
Долгая жизнь временных таблиц Засорение tempdb‚ конфликты имен‚ утечки памяти․ Явно вызывайте МенеджерВТ․УдалитьВременнуюТаблицу(ИмяВТ) в блоке Попытка․․․Исключение․․․КонецПопытки; ВКонце․․․․
Использование ВТ для малых данных (< 1000 строк) Накладные расходы на создание таблицы в СУБД выше выгоды․ Для малых наборов используйте ТаблицаЗначений и передачу через параметр запроса (&МойМассив)․

Жизненный цикл и область видимости

Понимание области видимости критично для архитектуры:

  • Сеансовый менеджер (Новый МенеджерВременныхТаблиц): Таблицы живут до конца сеанса или явного удаления․ Видны во всех запросах этого сеанса․
  • Транзакционный менеджер (внутри управляемой блокировки/транзакции): Таблицы удаляются при завершении транзакции (Commit/Rollback)․

Рекомендация: Для отчетов и фоновых задач используйте сеансовый менеджер с явным удалением в `ВКонце`․ Для атомарных операций обновления данных, транзакционный․

Резюме

Получение текста запроса для МенеджерВременныхТаблиц — это задача разработчика по формированию строки запроса с ключевым словом ПОМЕСТИТЬ <ИмяВТ>․ Сам менеджер предоставляет только имя таблицы (СоздатьВременнуюТаблицу) и инструменты для поддержания производительности (индексы‚ статистика)․

Ключевые моменты для высокопроизводительных решений 2024-2026 гг․:

  1. Явное описание структуры (ОписаниеВременнойТаблицы)․
  2. Обязательные индексы по полям JOIN и WHERE․
  3. Принудительное ОбновитьСтатистику после загрузки данных․
  4. Использование пакетного выполнения (ВыполнитьПакет) для массовых вставок․
  5. Грамотная очистка ресурсов в блоке ВКонце․

Соблюдение этих правил позволяет масштабировать 1С-решения на сотни пользователей и терабайты данных‚ минимизируя риски блокировок и таймаутов на уровне СУБД․