Имеет ли смысл уничтожать временные таблицы в запросах 1С

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

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

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

Прежде всего, проанализируем, что происходит «под капотом», когда мы создаем временную таблицу в 1С. Временные таблицы физически размещаются в системной базе данных SQL-сервера под названием tempdb. Независимо от того, используем ли мы простой пакетный запрос или объект МенеджерВременныхТаблиц, SQL-сервер выделяет пространство на диске и в оперативной памяти для хранения этих данных.

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

  1. Использование объекта Запрос без менеджера: В этом случае временные таблицы существуют только в рамках выполнения метода Выполнить(). Как только управление возвращается в код 1С, платформа инициирует неявную очистку временных таблиц в tempdb.
  2. Использование Менеджера временных таблиц: Здесь ситуация сложнее. Таблицы живут до тех пор, пока жив сам объект МенеджерВременныхТаблиц. Если менеджер определен как переменная внутри процедуры, он удалится при выходе из нее. Но если он передан в параметры или назначен реквизитом формы, таблицы будут занимать место в tempdb до тех пор, пока объект не будет явно очищен (присвоением Неопределено) или пока не завершится сеанс.

Влияние на производительность SQL-сервера и TempDB

Разберем ситуацию с точки зрения нагрузки на СУБД. База данных tempdb является общим ресурсом для всех баз данных на сервере. Чрезмерное накопление неиспользуемых временных таблиц может привести к нескольким негативным последствиям:

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

Во-вторых, существует проблема «состязания за страницы распределения» (PAGELATCH). SQL-сервер должен записывать метаданные о каждой новой временной таблице. Когда сотни сессий одновременно создают и не удаляют таблицы, возникают блокировки на системных страницах tempdb, что замедляет работу всех запросов в системе.

В-третьих, крайне важна статистика. SQL-сервер строит планы выполнения запросов на основе статистики данных в таблицах. Если мы создаем временную таблицу, используем ее, а затем в этом же пакете (или с тем же менеджером) пытаемся переиспользовать те же структуры, старая статистика может сбить оптимизатор с толку, что приведет к выбору неэффективного плана запроса (например, использованию Index Scan вместо Index Seek).

Стандарты разработки 1С и АПК

Обратимся к рекомендациям фирмы 1С. Инструмент автоматизированной проверки конфигураций (АПК) содержит правила, касающиеся работы с временными таблицами. Рассмотрим основные положения:

Если временная таблица содержит значительный объем данных (обычно счет идет на тысячи строк) и она больше не требуется для последующих шагов алгоритма, её необходимо уничтожать явно. Это освобождает память в rphost (где хранятся описания таблиц) и ресурсы в SQL-сервере.

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


// Создаем временную таблицу с данными
ВЫБРАТЬ
    Номенклатура,
    СуммаОстаток
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки;

// Используем её для основного расчета
ВЫБРАТЬ
    ВТ_Данные.Номенклатура,
    ВТ_Данные.СуммаОстаток * &Коэффициент КАК РасчетныйПоказатель
ИЗ
    ВТ_Данные;

// Очищаем ресурсы, так как далее ВТ_Данные не нужна
УНИЧТОЖИТЬ ВТ_Данные;

Защитное программирование и модульность

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

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

Когда уничтожение может мешать?

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

Однако этот аргумент относится только к процессу разработки. Для промышленного кода (production) приоритетом всегда должна быть производительность сервера, а не удобство отладки через консоль. Рассмотрим компромисс: на время отладки команду уничтожения можно комментировать, но в финальной версии кода она должна присутствовать для всех тяжелых таблиц.

Практические рекомендации

Подводя итог, выделим правила, которыми стоит руководствоваться при принятии решения об использовании УНИЧТОЖИТЬ:

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

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

← На главную