← Назад к вопросам

Что такое временные таблицы?

1.0 Junior🔥 201 комментариев
#Запросы и оптимизация#СУБД и хранение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Временные таблицы в 1С

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

Что это такое

Временная таблица (TempTable) — это таблица значений в памяти 1С, которая:

  • Живёт только в текущем сеансе
  • Может быть использована в SQL запросах как обычная таблица
  • Автоматически удаляется при завершении сеанса
  • Не требует прав на создание физических таблиц в БД

Два типа временных таблиц

1. Таблица значений (ТаблицаЗначений) — в памяти клиента

// Создание в памяти
Таблица = Новая ТаблицаЗначений();
Таблица.Колонки.Добавить("Товар");
Таблица.Колонки.Добавить("Количество");
Таблица.Колонки.Добавить("Цена");

// Добавление данных
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Товар = Справочники.Товары.НайтиПоКоду("001");
НоваяСтрока.Количество = 100;
НоваяСтрока.Цена = 500;

// Свойства: только клиент, очень быстро

2. Временная таблица на сервере БД

// Это таблица, которая реально создаётся в БД, но временная
Запрос = Новый Запрос(
    "СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ ДанныеДляОтчёта КАК
    |ВЫБРАТЬ
    |  Товары.Ссылка КАК Товар,
    |  Товары.Наименование,
    |  СУММА(Движения.Количество) КАК ОбщееКоличество
    |ИЗ
    |  РегистрНакопления.Движения КАК Движения
    |  ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Товары КАК Товары
    |    НА Движения.Товар = Товары.Ссылка
    |ГРУППИРОВАТЬ ПО
    |  Товары.Ссылка,
    |  Товары.Наименование");
Запрос.Выполнить();

// Теперь её можно использовать как обычную таблицу
Запрос2 = Новый Запрос(
    "ВЫБРАТЬ * ИЗ ДанныеДляОтчёта ГДЕ ОбщееКоличество > 100");

Отличия и когда использовать

ТаблицаЗначений (клиентская):

  • Живёт в памяти клиента
  • Очень быстро для маленьких наборов (до 10-50k строк)
  • Нельзя использовать в запросах SQL
  • Нельзя использовать между клиентом и сервером
// Пример: Обработка заказа
ТаблицаДетализации = Новая ТаблицаЗначений();
// ... заполнение ...
// Используется только локально для расчётов
ИтоговаяСумма = ВычислитьСумму(ТаблицаДетализации);

Временная таблица БД (серверная):

  • Создаётся реально в БД
  • Работает для больших объёмов (100k+)
  • Может использоваться в нескольких запросах
  • Требует выполнения на сервере
// Пример: Большой отчёт с агрегацией
Процедура СформироватьОтчёт() Экспорт
    
    // Создаём временную таблицу с базовыми данными
    ЗапросСоздание = Новый Запрос(
        "СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ ИсходныеДанные КАК
        |ВЫБРАТЬ ... ИЗ Документ.Заказ");
    ЗапросСоздание.Выполнить();
    
    // Используем эту таблицу в нескольких запросах
    ЗапросОсновной = Новый Запрос(
        "ВЫБРАТЬ * ИЗ ИсходныеДанные ГДЕ ...");
    
КонецПроцедуры

Практические примеры

Пример 1: Кэширование справочных данных

Процедура КэшироватьДанные() Экспорт
    
    // Вместо множества обращений к справочнику,
    // создаём временную таблицу
    
    ЗапросПолучения = Новый Запрос(
        "СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ КэшТовары КАК
        |ВЫБРАТЬ
        |  Ссылка КАК Товар,
        |  Наименование,
        |  Артикул,
        |  ВидУпаковки
        |ИЗ
        |  Справочник.Товары
        |ГДЕ
        |  НЕ ПометкаУдаления");
    ЗапросПолучения.Выполнить();
    
    // Теперь все дальнейшие запросы используют КэшТовары
    ЗапросОтчёта = Новый Запрос(
        "ВЫБРАТЬ
        |  ОстатокИТовары.Товар,
        |  КэшТовары.Наименование,
        |  КэшТовары.Артикул,
        |  ОстатокИТовары.Количество
        |ИЗ
        |  РегистрНакопления.ОстатокТоваров КАК ОстатокИТовары
        |  ВНУТРЕННЕЕ СОЕДИНЕНИЕ КэшТовары
        |    НА ОстатокИТовары.Товар = КэшТовары.Товар");
    
КонецПроцедуры

Пример 2: Промежуточные расчёты в отчёте

Процедура СформироватьСложныйОтчёт() Экспорт
    
    // Шаг 1: Создаём таблицу с доходами
    Запрос1 = Новый Запрос(
        "СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ Доходы КАК
        |ВЫБРАТЬ
        |  Статья,
        |  СУММА(Сумма) КАК СуммаДохода
        |ИЗ РегистрСведений.Доходы
        |ГРУППИРОВАТЬ ПО Статья");
    Запрос1.Выполнить();
    
    // Шаг 2: Создаём таблицу с расходами
    Запрос2 = Новый Запрос(
        "СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ Расходы КАК
        |ВЫБРАТЬ
        |  Статья,
        |  СУММА(Сумма) КАК СуммаРасхода
        |ИЗ РегистрСведений.Расходы
        |ГРУППИРОВАТЬ ПО Статья");
    Запрос2.Выполнить();
    
    // Шаг 3: Объединяем и рассчитываем прибыль
    ЗапросИтоговый = Новый Запрос(
        "ВЫБРАТЬ
        |  ВЫБОР
        |    КОГДА Доходы.Статья НЕ NULL ТОГДА Доходы.Статья
        |    ИНАЧЕ Расходы.Статья
        |  КОНЕЦ КАК Статья,
        |  ВЫБОР КОГДА Доходы.СуммаДохода НЕ NULL ТОГДА Доходы.СуммаДохода ИНАЧЕ 0 КОНЕЦ КАК Доход,
        |  ВЫБОР КОГДА Расходы.СуммаРасхода НЕ NULL ТОГДА Расходы.СуммаРасхода ИНАЧЕ 0 КОНЕЦ КАК Расход,
        |  (ВЫБОР КОГДА Доходы.СуммаДохода НЕ NULL ТОГДА Доходы.СуммаДохода ИНАЧЕ 0 КОНЕЦ) -
        |  (ВЫБОР КОГДА Расходы.СуммаРасхода НЕ NULL ТОГДА Расходы.СуммаРасхода ИНАЧЕ 0 КОНЕЦ) КАК Прибыль
        |ИЗ
        |  Доходы
        |  ПОЛНОЕ СОЕДИНЕНИЕ Расходы
        |    НА Доходы.Статья = Расходы.Статья");
    
    ТаблицаРезультата = ЗапросИтоговый.Выполнить().Выгрузить();
    
КонецПроцедуры

Пример 3: Обработка больших объёмов данных пакетами

Процедура ОбработатьДокументыПакетами() Экспорт
    
    // Создаём временную таблицу документов для обработки
    ЗапросСоздания = Новый Запрос(
        "СОЗДАТЬ ВРЕМЕННУЮ ТАБЛИЦУ ДокументыКОбработке КАК
        |ВЫБРАТЬ
        |  Ссылка,
        |  Номер,
        |  Дата,
        |  Сумма
        |ИЗ Документ.Заказ
        |ГДЕ
        |  Дата >= &ДатаНачала
        |  И Статус = &СтатусНовый");
    ЗапросСоздания.УстановитьПараметр("ДатаНачала", БольшаяДата(,,-30)); // 30 дней назад
    ЗапросСоздания.УстановитьПараметр("СтатусНовый", Перечисления.СтатусыДокумента.Новый);
    ЗапросСоздания.Выполнить();
    
    // Обработка пакетами по 100 документов
    ЗапросПакетов = Новый Запрос(
        "ВЫБРАТЬ * ИЗ ДокументыКОбработке ПОРЯДОК ПО Дата ПРЕДЕЛ 100");
    
    Цикл
        РезультатПакета = ЗапросПакетов.Выполнить();
        Если РезультатПакета.Пусто() Тогда
            Прервать; // Все обработаны
        КонецЕсли;
        
        Для Каждого Документ Из РезультатПакета Цикл
            ОбработатьДокумент(Документ.Ссылка);
        КонецЦикла;
        
    КонецЦикла;
    
КонецПроцедуры

Правила использования

1. Область видимости:

  • Временная таблица видна только в текущем соединении
  • В фоновых заданиях — отдельное соединение
  • Нельзя передать временную таблицу между сеансами

2. Производительность:

  • Для маленьких наборов < 10k — лучше ТаблицаЗначений
  • Для больших наборов > 100k — временная таблица БД
  • Индексы создаются автоматически

3. Очистка:

// В конце работы явно удаляй временные таблицы
ЗапросУдаления = Новый Запрос(
    "УДАЛИТЬ ИЗ ВременнаяТаблица");
ЗапросУдаления.Выполнить();

// Или просто заверши сеанс — удалятся сами

4. Типичные ошибки:

  • Использование временной таблицы после завершения сеанса
  • Забыли, что временная таблица видна только в текущем соединении
  • Создали индекс без необходимости
  • Не удалили временную таблицу в конце — занимает память

Примеры оптимизации

// ❌ ПЛОХО: Много небольших запросов
Для н = 1 По 1000 Цикл
    Запрос = Новый Запрос("ВЫБРАТЬ ... ГДЕ ID = " + Н);
    Результат = Запрос.Выполнить();
КонецЦикла;

// ✅ ХОРОШО: Одна временная таблица
ЗапросВсе = Новый Запрос("ВЫБРАТЬ * ИЗ Таблица");
Таблица = ЗапросВсе.Выполнить().Выгрузить();
// Работаешь с таблицей в памяти

Заключение

Временные таблицы — это essential инструмент для:

  • Оптимизации сложных отчётов
  • Обработки больших объёмов данных
  • Кэширования промежуточных результатов
  • Разделения логики на понятные шаги

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

Что такое временные таблицы? | PrepBro