Вопрос о необходимости явного уничтожения временных таблиц (ВТ) в пакете запроса часто становится предметом споров среди разработчиков 1С. На первый взгляд кажется, что платформа 1С:Предприятие достаточно интеллектуальна, чтобы самостоятельно очистить ресурсы. Однако при работе с высоконагруженными системами и большими объемами данных этот вопрос переходит из разряда «эстетики кода» в плоскость производительности и стабильности всей системы. В этой статье мы подробно разберем, как работают временные таблицы на уровне платформы и СУБД, и выясним, когда команда УНИЧТОЖИТЬ жизненно необходима, а когда без нее можно обойтись.
Прежде всего, проанализируем, что происходит «под капотом», когда мы создаем временную таблицу в 1С. Временные таблицы физически размещаются в системной базе данных SQL-сервера под названием tempdb. Независимо от того, используем ли мы простой пакетный запрос или объект МенеджерВременныхТаблиц, SQL-сервер выделяет пространство на диске и в оперативной памяти для хранения этих данных.
Рассмотрим два основных сценария жизненного цикла временных таблиц:
Выполнить(). Как только управление возвращается в код 1С, платформа инициирует неявную очистку временных таблиц в tempdb.МенеджерВременныхТаблиц. Если менеджер определен как переменная внутри процедуры, он удалится при выходе из нее. Но если он передан в параметры или назначен реквизитом формы, таблицы будут занимать место в tempdb до тех пор, пока объект не будет явно очищен (присвоением Неопределено) или пока не завершится сеанс.Разберем ситуацию с точки зрения нагрузки на СУБД. База данных tempdb является общим ресурсом для всех баз данных на сервере. Чрезмерное накопление неиспользуемых временных таблиц может привести к нескольким негативным последствиям:
Во-первых, это разрастание файлов данных и лога транзакций tempdb. Даже если таблицы «маленькие», их большое количество от разных пользователей может быстро исчерпать дисковое пространство, что приведет к остановке всей СУБД.
Во-вторых, существует проблема «состязания за страницы распределения» (PAGELATCH). SQL-сервер должен записывать метаданные о каждой новой временной таблице. Когда сотни сессий одновременно создают и не удаляют таблицы, возникают блокировки на системных страницах tempdb, что замедляет работу всех запросов в системе.
В-третьих, крайне важна статистика. SQL-сервер строит планы выполнения запросов на основе статистики данных в таблицах. Если мы создаем временную таблицу, используем ее, а затем в этом же пакете (или с тем же менеджером) пытаемся переиспользовать те же структуры, старая статистика может сбить оптимизатор с толку, что приведет к выбору неэффективного плана запроса (например, использованию Index Scan вместо Index Seek).
Обратимся к рекомендациям фирмы 1С. Инструмент автоматизированной проверки конфигураций (АПК) содержит правила, касающиеся работы с временными таблицами. Рассмотрим основные положения:
Если временная таблица содержит значительный объем данных (обычно счет идет на тысячи строк) и она больше не требуется для последующих шагов алгоритма, её необходимо уничтожать явно. Это освобождает память в rphost (где хранятся описания таблиц) и ресурсы в SQL-сервере.
Пример правильной структуры пакета запроса:
// Создаем временную таблицу с данными
ВЫБРАТЬ
Номенклатура,
СуммаОстаток
ПОМЕСТИТЬ ВТ_Данные
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки;
// Используем её для основного расчета
ВЫБРАТЬ
ВТ_Данные.Номенклатура,
ВТ_Данные.СуммаОстаток * &Коэффициент КАК РасчетныйПоказатель
ИЗ
ВТ_Данные;
// Очищаем ресурсы, так как далее ВТ_Данные не нужна
УНИЧТОЖИТЬ ВТ_Данные;
Выясним еще одну причину использования команды УНИЧТОЖИТЬ — это предотвращение конфликтов имен. В сложных программных продуктах, где запросы могут собираться динамически или вложенными вызовами процедур, легко столкнуться с ошибкой «Таблица уже существует». Явное уничтожение таблицы перед её потенциальным повторным созданием или после использования гарантирует предсказуемость работы кода.
Проанализируем ситуацию с «простотой кода» против «надежности». Многие разработчики пренебрегают уничтожением, аргументируя это тем, что запрос «маленький». Однако системы имеют свойство расти. То, что сегодня является запросом на 5 строк, завтра может превратиться в сложный алгоритм внутри цикла. В таких случаях отсутствие культуры очистки ресурсов приводит к трудноуловимым ошибкам производительности.
Существует специфический аспект, связанный с отладкой. При разработке сложных запросов программисты часто используют консоли запросов. Если в тексте запроса в середине пакета стоит УНИЧТОЖИТЬ ВТ_ИмяТаблицы, то при попытке посмотреть содержимое этой таблицы в консоли после выполнения всего пакета, вы получите ошибку, так как таблица уже удалена.
Однако этот аргумент относится только к процессу разработки. Для промышленного кода (production) приоритетом всегда должна быть производительность сервера, а не удобство отладки через консоль. Рассмотрим компромисс: на время отладки команду уничтожения можно комментировать, но в финальной версии кода она должна присутствовать для всех тяжелых таблиц.
Подводя итог, выделим правила, которыми стоит руководствоваться при принятии решения об использовании УНИЧТОЖИТЬ:
УНИЧТОЖИТЬ перед созданием таблицы с тем же именем, чтобы избежать исключительных ситуаций.Таким образом, хотя для микро-запросов из двух пакетов уничтожение таблиц не принесет видимого прироста скорости, внедрение этой практики в ежедневную работу является признаком высокого профессионализма и гарантией стабильности системы при масштабировании данных. Мы рекомендуем рассматривать команду УНИЧТОЖИТЬ не как лишнюю строку кода, а как необходимый инструмент управления ресурсами сервера.