К статье
Практический материал

Разработка и Конфигурация · 13 мин

Зачем удалять временные таблицы в 1С

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

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

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

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

Где хранятся временные таблицы и почему это важно

Когда запрос с конструкцией «ПОМЕСТИТЬ В МояТаблица» выполняется, платформа создаёт реальную временную таблицу на сервере СУБД. В клиент-серверном варианте это физические объекты в служебной области базы данных (в Microsoft SQL Server — в tempdb), в файловом варианте — структуры в памяти процесса. В обоих случаях таблица потребляет ресурсы: память, место, а при больших объёмах — ещё и дисковые операции.

Ключевой момент: временная таблица живёт не в рамках одного запроса, а в рамках менеджера временных таблиц. Пока менеджер существует и таблица не удалена, она доступна последующим запросам — и продолжает занимать ресурсы. Если менеджер передаётся между процедурами или используется в цикле, таблицы накапливаются.

В файловом варианте ситуация дополнительно усугубляется тем, что вся работа идёт в рамках одного процесса: рост потребления памяти напрямую влияет на сеанс пользователя. В клиент-серверном варианте страдает сервер СУБД, а значит — все пользователи, работающие с этой базой.

Как неудалённые таблицы влияют на производительность

Одна забытая таблица на тысячу строк обычно незаметна. Проблемы начинаются в типовых сценариях: обработка в цикле обходит тысячи документов и на каждой итерации помещает данные во временную таблицу; отчёт строит цепочку из десятка промежуточных таблиц; процедура вызывается массово при проведении документов. В этих случаях объём данных в менеджере растёт линейно или хуже.

Симптомы узнаваемы: время выполнения обработки растёт непропорционально объёму данных, потребление памяти рабочим процессом или SQL-сервером увеличивается в ходе выполнения и не возвращается к исходному уровню, на больших базах появляются ошибки нехватки памяти или тайм-ауты. В tempdb на SQL Server можно наблюдать рост размера файлов во время выполнения «тяжёлой» операции.

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

Время выполненияРастёт в ходе обработки

Замерьте длительность первых и последних итераций цикла — разница в разы указывает на накопление таблиц

Память сервераРастёт и не освобождается

Следите за потреблением памяти процессом rphost или sqlservr во время выполнения операции

Размер tempdbУвеличивается при работе

На SQL Server проверьте рост tempdb в момент выполнения тяжёлого отчёта или обработки

Когда удалять временные таблицы обязательно

Правило простое: таблицу нужно удалять сразу после того, как она перестала быть нужна. На практике есть несколько ситуаций, где это критично, и несколько — где можно положиться на автоматическое освобождение.

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

Если менеджер временных таблиц создаётся локально внутри небольшой процедуры и не передаётся наружу, можно не удалять таблицы по одной — при выходе из процедуры и исчезновении ссылки на менеджер платформа освободит ресурсы. Но даже здесь явное удаление считается хорошим тоном: код становится предсказуемым и безопасным при дальнейших доработках, когда процедура может вырасти или начать вызываться в цикле.

Маршрут решения

Когда нужно явное удаление

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

Как правильно удалить временную таблицу

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

Типовой фрагмент кода выглядит так: сначала основной запрос помещает данные и использует их, затем отдельный короткий запрос уничтожает ненужные таблицы. Важно, чтобы у запроса на уничтожение был назначен тот же объект менеджера, иначе он просто не найдёт таблицу и вызовет ошибку.

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

Запрос.Текст =

"ВЫБРАТЬ Продажи.Номенклатура, СУММА(Продажи.Количество) КАК Количество

|ПОМЕСТИТЬ ВТ_Итоги

|ИЗ РегистрНакопления.Продажи.Обороты(&Начало, &Конец) КАК Продажи

|СГРУППИРОВАТЬ ПО Продажи.Номенклатура";

Запрос.Выполнить();

// ... использование ВТ_Итоги в следующих запросах ...

ЗапросУдаление = Новый Запрос;

ЗапросУдаление.МенеджерВременныхТаблиц = МенеджерВТ;

ЗапросУдаление.Текст = "УНИЧТОЖИТЬ ВТ_Итоги";

ЗапросУдаление.Выполнить();

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

Альтернативы: как уменьшить число временных таблиц

Не каждая временная таблица вообще нужна. Часть сценариев решается проще: вложенными запросами, объединениями, виртуальными таблицами регистров. Если промежуточный результат используется один раз и сразу после создания, вложенный запрос может быть читабельнее и не требует управления временем жизни таблицы.

Другой приём — пересмотреть гранулярность: вместо десяти промежуточных таблиц иногда достаточно двух-трёх, если правильно сгруппировать данные на раннем этапе. Чем меньше таблиц живёт одновременно, тем проще контролировать ресурсы и тем меньше кода на уничтожение.

Для передачи данных между запросами вне цикла иногда выгоднее таблица значений: она живёт в памяти сеанса, освобождается сборщиком мусора и не нагружает СУБД. Но при больших объёмах и необходимости соединений с данными базы временная таблица обычно эффективнее — выбор зависит от задачи.

Способы организации промежуточных данных

Временная таблица + явное УНИЧТОЖИТЬ

Подходит для больших объёмов и соединений с таблицами базы; требует дисциплины удаления

Вложенный запрос

Подходит для одноразового использования; не требует управления, но снижает читаемость при сложной логике

Таблица значений как параметр

Подходит для данных, полученных не из запроса; ограничение — нельзя индексировать и сложно соединять при больших объёмах

Локальный менеджер без явного удаления

Допустимо в коротких процедурах с однократным выполнением; рискованно при переносе кода в цикл

Типичные ошибки и риски

Самая распространённая ошибка — создание временной таблицы внутри цикла без удаления. Даже если имя таблицы одно и то же, разработчик иногда создаёт новый менеджер на каждой итерации и теряет к нему доступ: старые таблицы продолжают жить до конца сеанса или до явного освобождения, и память растёт.

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

Третья группа ошибок — преждевременное удаление: таблица уничтожается, а ниже по коду какой-то запрос ещё обращается к ней. Такое всплывает при доработках, когда в середину старой процедуры добавляют новый запрос. Защита простая: удалять таблицы максимально близко к точке последнего использования и после изменений прогонять весь сценарий целиком.

Типичные ошибки
01
Создание таблиц в цикле без УНИЧТОЖИТЬ — память растёт на каждой итерации, обработка замедляется или падает
02
Новый менеджер временных таблиц на каждой итерации — старые таблицы теряются и не освобождаются до конца сеанса
03
Уничтожение через запрос с другим менеджером — ошибка «таблица не найдена» и аварийное завершение
04
Удаление таблицы до её последнего использования — ошибки после доработок кода
05
Хранение менеджера в реквизите формы или глобальной переменной — таблицы живут весь сеанс пользователя

Как проверить, что проблема решена

Проверка строится на замерах до и после изменения кода. Минимальный набор: время выполнения всей операции, время отдельных итераций цикла, потребление памяти серверным процессом. Если после добавления УНИЧТОЖИТЬ длительность итераций выровнялась, а память перестала расти — причина была именно в накоплении таблиц.

Для тонкой диагностики в клиент-серверном варианте используют технологический журнал с событиями DBMSSQL и мониторинг tempdb на стороне СУБД. В файловом варианте достаточно наблюдения за памятью процесса и замеров через функции даты и времени или встроенный замер производительности в конфигураторе.

Контрольные точки

Как проверить результат

Длительность итераций цикла
Норма

Время первой и последней итерации отличается незначительно

Тревожный признак

Каждая следующая итерация заметно медленнее предыдущей

Память серверного процесса
Норма

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

Тревожный признак

Память растёт монотонно и не возвращается к исходному уровню

Повторный запуск обработки
Норма

Второй запуск выполняется за то же время, что и первый

Тревожный признак

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

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

Удобный приём — давать временным таблицам префикс по этапу (например, ВТ_Отбор_, ВТ_Расчет_) и удалять их группой одним пакетным запросом в конце этапа. Так проще при code review увидеть, какие таблицы должны быть уничтожены, и не пропустить ни одной.
ПЗ
Практическое замечание
Итог

Что важно запомнить

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

Частые вопросы

Удалятся ли временные таблицы сами, если ничего не делать?

Да, но не сразу. Таблицы освобождаются, когда уничтожается менеджер временных таблиц — обычно при выходе из процедуры, где он создан, и исчезновении всех ссылок на него. Если менеджер хранится в реквизите формы или используется в длинной цепочке вызовов, таблицы могут жить очень долго, поэтому в таких сценариях нужно явное удаление.

Что будет, если уничтожить несуществующую таблицу?

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

Можно ли удалить сразу все временные таблицы менеджера?

Отдельной команды «очистить всё» нет. Варианта два: перечислить все таблицы операторами УНИЧТОЖИТЬ в одном пакетном запросе или создать новый менеджер временных таблиц вместо старого — тогда старый со всеми таблицами будет освобождён, если на него не осталось ссылок.

Влияют ли временные таблицы на работу других пользователей?

В клиент-серверном варианте — да, косвенно. Таблицы занимают ресурсы общего сервера СУБД, включая tempdb, поэтому «тяжёлая» обработка с накоплением таблиц может замедлить работу всей базы. В файловом варианте влияние ограничено сеансом конкретного пользователя.

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

Там, где платформа управляет запросами сама (например, при выполнении схемы компоновки данных), разработчик не управляет временными таблицами напрямую — их жизненным циклом занимается платформа. Явное удаление требуется только в коде, где вы сами создаёте менеджер и выполняете запросы с ПОМЕСТИТЬ.