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

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

В процессе разработки сложных систем на платформе 1С:Предприятие 8 программисты часто сталкиваются с ситуацией, когда регламентные задания или тяжелые запросы начинают блокировать работу обычных пользователей. Рассмотрим ситуацию, когда выполнение процедуры по расписанию вызывает "торможение" при проведении документов реализации, и разберем, как правильно работать с временными таблицами, блокировками и правами доступа.

Анализ механизма работы временных таблиц

В представленном в теме коде используется объект МенеджерВременныхТаблиц. Важно понимать, что временные таблицы физически создаются в базе данных (в TempDB для MS SQL Server). Они существуют до тех пор, пока объект менеджера не будет удален из памяти или пока таблица не будет уничтожена явно.

Проанализируем вопрос автора: нужно ли уничтожать таблицу и где это делать? Сама по себе временная таблица редко является прямой причиной "торможения" проведения у других пользователей, если только она не переполняет дисковое пространство TempDB. Однако неявное хранение данных в памяти и базе нагружает ресурсы. Уничтожать временную таблицу следует сразу после того, как данные из нее были использованы в последнем запросе. Это делается командой в тексте запроса:


Запрос.Текст = "УНИЧТОЖИТЬ ВТНоваяТаблица";
Запрос.Выполнить();

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

Влияние транзакционных блокировок

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

  1. Выполняется огромный запрос, который подготавливает данные (может занимать длительное время).
  2. Открывается транзакция командой НачатьТранзакцию.
  3. Устанавливается управляемая блокировка на весь регистр ПланыДоставки.
  4. Выполняется еще один запрос к временной таблице.
  5. Производится запись в регистр через набор записей.
  6. Транзакция фиксируется.

Если этот процесс занимает 450 секунд (7.5 минут) и запускается каждые 10 минут, то 75% рабочего времени регистр заблокирован для записи. Любой пользователь, пытающийся провести документ, который должен сделать запись в этот же регистр или связанные таблицы, будет ждать завершения этой транзакции. Именно это пользователи воспринимают как "торможение" системы.

Оптимизация структуры запроса

Проанализируем текст запроса из сообщения. В нем есть несколько критических моментов, которые замедляют выполнение:

1. Соединение с виртуальными таблицами. В коде происходит соединение физических таблиц документов с виртуальными таблицами оборотов (например, РегистрНакопления.ЗаказыПокупателей.Обороты). Платформа 1С работает гораздо эффективнее, если сначала выбрать данные из виртуальной таблицы во временную, проиндексировать её, а затем соединять с другими данными.

2. Отсутствие индексов. Временные таблицы, такие как ВТНастройки, ВТОтборЗаказы, ВТНоваяТаблица, участвуют в соединениях. Без создания индексов по полям соединения (например, по полю Организация или Контрагент), СУБД вынуждена выполнять полное сканирование таблицы (Table Scan) при каждом сопоставлении строк. Рассмотрим пример создания индекса:


// В тексте запроса при помещении в таблицу
"ПОМЕСТИТЬ ВТОтборЗаказы
ИЗ ...
ИНДЕКСИРОВАТЬ ПО Организация"

Проблема RLS (права доступа)

В ходе обсуждения автор заметил, что под полными правами (Администратор) документ проводится быстро, а у бухгалтеров — медленно. Это явный признак влияния RLS (Row Level Security). Когда пользователь с ограниченными правами выполняет запрос, система автоматически добавляет к нему условия фильтрации по каждой таблице. Это может превратить один простой запрос в чудовищную конструкцию с десятками подзапросов.

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

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


УстановитьПривилегированныйРежим(Истина);
// Далее идет выполнение запроса и работа с данными
УстановитьПривилегированныйРежим(Ложь);

Это позволит запросу выполняться по "прямым" индексам таблиц без наслоения условий RLS, что значительно ускорит работу для обычных пользователей.

Рекомендации по замеру производительности

Чтобы точно выяснить причину торможения, проанализируем методику замера производительности. Если точка останова не срабатывает у пользователя, необходимо:

  1. Включить отладку на сервере (параметр -debug в строке запуска службы агента 1С).
  2. В конфигураторе использовать меню "Отладка" -> "Подключение", выбрать сеанс нужного пользователя.
  3. Запустить "Замер производительности" непосредственно перед тем, как пользователь нажмет кнопку проведения.

В результате замера стоит обратить внимание на строки с методами Записать() или Выполнить(). Если метод Записать() занимает аномально много времени, значит проблема в блокировках (транзакция ждет освобождения ресурсов). Если Выполнить() у запроса — проблема в оптимизации самого текста запроса или в индексах.

Итоговый алгоритм действий

Для исправления ситуации выполним следующие шаги:

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

← На главную