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

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

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

Механика работы временных таблиц на уровне платформы и СУБД

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

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

Влияние на оперативную память и Buffer Pool

Важно понимать, что временные таблицы нагружают не только дисковую подсистему, но и оперативную память сервера СУБД. Рассмотрим процесс кэширования: SQL Server старается держать страницы данных временных таблиц в Buffer Pool (оперативной памяти) для ускорения доступа. Если мы создаем огромную таблицу объемом в несколько гигабайт и не удаляем ее сразу после использования, она продолжает удерживать место в оперативной памяти, вытесняя оттуда полезные данные других таблиц (индексы, часто используемые записи). Это приводит к росту чтений с диска для других запросов и общему замедлению системы.

Проанализируем пример кода, где явное удаление оправдано:


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

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

Проблема разрастания базы tempdb

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

Практическая рекомендация: Если объем данных во временной таблице превышает 100 000 строк или 100 Мб, её стоит удалять явно. Это «золотое правило» помогает избежать внезапного исчерпания места на диске сервера СУБД.

Особый случай: Ошибка в динамических списках

Рассмотрим важный нюанс, связанный с использованием временных таблиц в динамических списках. Программисты иногда пытаются оптимизировать сложные списки, создавая временные таблицы в тексте запроса и добавляя в конце УНИЧТОЖИТЬ. Это приводит к фатальной ошибке платформы, часто с дампом памяти или текстом "Недопустимое состояние объекта [entext - src\Select.cpp]".

Разберем причину: динамический список считывает данные порциями (по мере прокрутки пользователем). Если вы уничтожаете таблицу в тексте запроса, то при попытке списка прочитать следующую порцию данных (следующие 20-30 строк) временной таблицы в СУБД уже не существует. Запомните: в запросах динамических списков использовать команду УНИЧТОЖИТЬ категорически нельзя.

Специфика работы с PostgreSQL

Если ваша база работает под управлением PostgreSQL, вопрос удаления таблиц стоит еще острее. В этой СУБД создание временных таблиц может приводить к «раздуванию» (bloat) системного каталога pg_class. Если сессии пользователей долго не закрываются (например, в режиме обычного приложения), а временные таблицы создаются и не удаляются явно, это замедляет работу планировщика запросов. Явное УНИЧТОЖИТЬ помогает поддерживать системные таблицы метаданных СУБД в чистоте.

Конфликты блокировок в системных страницах (PFS, GAM)

Для высоконагруженных систем (HighLoad) существует и обратная сторона медали. Посмотрим на ситуацию глубже: при очень частом (тысячи раз в секунду) создании и удалении мелких временных таблиц в MS SQL Server могут возникать задержки на системных страницах распределения пространства (PFS, GAM страницы). Если таблицы крошечные (несколько строк), иногда выгоднее позволить платформе удалить их пакетно в конце, чтобы не создавать лишнюю нагрузку на системные объекты tempdb постоянными командами DROP.

Подведем итоги и сформируем правила хорошего тона

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

  1. Всегда удаляйте временные таблицы при использовании МенеджераВременныхТаблиц, если они больше не нужны по ходу алгоритма. Это критично для экономии памяти сервера приложений и СУБД.
  2. Используйте УНИЧТОЖИТЬ для больших объемов данных (более 100к строк), даже если менеджер не установлен. Это освобождает Buffer Pool СУБД и предотвращает разрастание tempdb.
  3. Не загромождайте код удалением мелких таблиц (на 10-100 строк) в простых разовых запросах без менеджера — здесь автоматика платформы справится не хуже.
  4. Категорически избегайте УНИЧТОЖИТЬ в динамических списках, чтобы не вызвать падение платформы.
  5. Следите за индексами. Если вы создали индекс на временной таблице (ИНДЕКСИРОВАТЬ ПО...), такая таблица становится «дороже» для сервера. Её удаление после использования должно быть приоритетным.

Соблюдение этих правил не только повышает стабильность вашей системы, но и демонстрирует профессиональный подход к разработке («чистый код»), облегчая дальнейшую поддержку и оптимизацию конфигурации.

← На главную