Влияет ли явное удаление временных таблиц в запросе 1С на производительность системы?

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

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

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

Как устроены временные таблицы на уровне СУБД

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

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

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


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Товар,
    Номенклатура.Код КАК Код
ПОМЕСТИТЬ ВТ_Товары
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Услуга = ЛОЖЬ;
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Товары.Товар,
    ВТ_Товары.Код
ИЗ
    ВТ_Товары КАК ВТ_Товары;
;
////////////////////////////////////////////////////////////////////////////////
УНИЧТОЖИТЬ ВТ_Товары

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

Что происходит при вызове команды УНИЧТОЖИТЬ

На уровне СУБД команда платформы УНИЧТОЖИТЬ транслируется в инструкции удаления объектов (такие как DROP TABLE или TRUNCATE TABLE). Сама по себе эта операция в СУБД выполняется крайне быстро — за считанные миллисекунды. СУБД просто делает пометку в своих системных таблицах (метаданных), что данные страницы памяти и диска теперь свободны и могут быть использованы повторно.

Однако в высоконагруженных системах с тысячами активных пользователей этот процесс может столкнуться со следующими проблемами:

  1. Блокировки и конкуренция за метаданные в MS SQL Server: При очень высокой интенсивности создания и удаления временных таблиц база данных tempdb начинает испытывать перегрузку. Возникают ожидания типа PAGELATCH, когда разные потоки пытаются одновременно изменить структуру метаданных системной базы. В таких ситуациях операция удаления таблицы может «подвиснуть» на несколько секунд, парализуя работу смежных запросов. Для борьбы с этим в современных версиях MS SQL Server (начиная с 2019 года) рекомендуется включать режим оптимизации метаданных MEMORY_OPTIMIZED TEMPDB_METADATA.
  2. Оптимизация в PostgreSQL: Разработчики платформы 1С совместно с Postgres Professional реализовали специальное расширение fasttrun, которое выполняет усечение таблиц через функцию fasttruncate() без изменения системных каталогов. Это позволяет PostgreSQL уничтожать временные таблицы практически мгновенно и без лишних блокировок.
  3. Отложенное создание файлов в новых версиях платформы (8.3.25+): Платформа 1С непрерывно развивается. В современных релизах реализован механизм, при котором файлы временной таблицы в СУБД вообще физически не создаются на диске, если объем данных в ней не превышает 32 Кб. Вся работа происходит исключительно в оперативной памяти, что нивелирует накладные расходы на создание и удаление мелких таблиц.

Жизненный цикл временных таблиц в 1С

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

Сценарий 1: Работа без Менеджера временных таблиц

Рассмотрим простейший вызов запроса без явного создания менеджера временных таблиц:


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

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

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

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

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


МВТ = Новый МенеджерВременныхТаблиц;

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

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

Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МВТ;
Запрос2.Текст = 
    "ВЫБРАТЬ * ИЗ ВТ_Товары ГДЕ ...";
Результат = Запрос2.Выполнить();

В данном случае временная таблица ВТ_Товары будет жить в СУБД до тех пор, пока жив сам объект МВТ (переменная МВТ находится в области видимости). Если этот менеджер передан как параметр в глобальный модуль или удерживается в реквизитах какой-либо долгоживущей формы, данные в СУБД будут продолжать занимать место в tempdb и оперативной памяти сервера.

Проанализируем последствия длительного удержания МВТ без очистки:

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

Механизм переиспользования временных таблиц

Рассмотрим еще один важный архитектурный нюанс платформы «1С:Предприятие» — кэширование и повторное использование структур таблиц.

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

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

Проблема отладки при явном уничтожении

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

Стандарты разработки БСП (Библиотеки стандартных подсистем)

В крупных тиражных решениях фирмы 1С (таких как ERP, ЗУП, Комплексная автоматизация) правила работы с временными таблицами жестко регламентированы. В коде БСП активно используются специализированные программные методы очистки.

Например, в коде часто можно встретить конструкции вызова процедур общего назначения, которые программно формируют запросы на удаление таблиц:


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

ЗарплатаКадры.УничтожитьВТ(МассивТаблицДляУдаления, МВТ);

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

Рекомендации: Когда использовать УНИЧТОЖИТЬ, а когда нет

Подводя итог нашему анализу, сформулируем четкие и практичные правила для разработчиков.

Явное уничтожение НЕ ТРЕБУЕТСЯ:

  1. В простых пакетных запросах без использования МВТ: Платформа гарантированно и максимально эффективно очистит все таблицы самостоятельно в момент завершения метода Выполнить().
  2. При работе с небольшими объемами данных (до нескольких тысяч строк): Накладные расходы на выполнение самой инструкции удаления могут превысить потенциальную выгоду от мгновенного освобождения нескольких килобайт в tempdb.
  3. В циклических алгоритмах с частым пересозданием одинаковых таблиц: Дайте платформе возможность переиспользовать уже созданные структуры таблиц в СУБД.

Явное уничтожение ОБЯЗАТЕЛЬНО:

  1. При работе с долгоживущими Менеджерами временных таблиц: Если МВТ передается между множеством процедур и функций, живет в течение длительных расчетов или хранится в реквизитах модулей.
  2. При обработке огромных массивов данных (сотни тысяч и миллионы строк): Освобождение занимаемого дискового пространства и оперативной памяти СУБД сразу после использования таблицы предотвратит деградацию производительности всей системы и исключит риск переполнения диска tempdb.
  3. В теле длинных циклов, использующих один и тот же МВТ: Если внутри цикла в МВТ постоянно помещаются новые временные таблицы, их обязательно нужно уничтожать на каждой итерации, иначе память сервера будет исчерпана за несколько шагов цикла.

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

← На главную