Многие разработчики и администраторы 1С сталкивались с мистической ситуацией: есть отчет, который большую часть времени формируется за считанные секунды или минуты. Но иногда, без видимых причин, он "вешается" и выполняется часами, вызывая гнев пользователей. При этом в тестовой базе под тем же пользователем все "летает".
В этой статье мы подробно разберем, почему возникает такое поведение, особенно в конфигурациях вроде "Управление торговлей 11" (УТ 11), "ERP" или "Комплексная автоматизация", где активно используется механизм ограничения прав доступа на уровне записей (RLS). Мы проанализируем технические аспекты работы платформы 1С в связке с MS SQL Server и выработаем стратегию решения.
В обсуждаемой теме автор указал, что в базе включен RLS (ограничение доступа на уровне записей), и каждый пользователь видит только свои данные. Это один из ключевых факторов.
Давайте разберемся, как это работает. Когда вы пишете запрос в 1С, например, к регистру продаж, платформа при включенном RLS не просто транслирует ваш текст в SQL. Она автоматически, "под капотом", добавляет к запросу дополнительные условия и соединения с таблицами прав доступа.
Что происходит внутри:
Если в коде запроса вы забыли ключевое слово РАЗРЕШЕННЫЕ, система будет пытаться проверить права даже на те записи, которые, возможно, будут отсечены дальнейшими условиями, что создает колоссальную нагрузку.
Рекомендация: Всегда используйте РАЗРЕШЕННЫЕ в запросах отчетов, если логика не требует обратного.
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Продажи.Номенклатура,
Продажи.КоличествоОборот
ИЗ
РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты AS Продажи
Это наиболее вероятная причина того, почему отчет "то работает, то тормозит". Рассмотрим механизм работы оптимизатора запросов MS SQL Server.
Когда запрос выполняется впервые (или после очистки кэша), SQL Server строит план выполнения. Он смотрит на параметры, с которыми запущен отчет в данный момент.
Сценарий возникновения проблемы:
Nested Loops). Этот план сохраняется в кэше.В тестовой базе это не воспроизводится, потому что там кэш планов обычно пустой или другой, и для вашего теста SQL строит свежий, адекватный план.
Частая ошибка при написании отчетов — соединение с виртуальными таблицами без предварительного отбора. Рассмотрим пример, который часто приводит к тормозам.
Плохой подход:
ВЫБРАТЬ
...
ИЗ
Справочник.Номенклатура КАК Спр
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
ПО Спр.Ссылка = Остатки.Номенклатура
ГДЕ
Спр.Ссылка В (&СписокТоваров)
В этом случае сначала может быть рассчитана полная виртуальная таблица остатков (по всем товарам), и только потом произойдет соединение. Если добавить сюда RLS, SQL Server может окончательно запутаться в выборе плана.
Правильный подход:
Мы должны помочь оптимизатору. Для этого необходимо сначала отобрать нужные данные во временную таблицу, а затем использовать параметры виртуальной таблицы.
// Шаг 1: Помещаем список товаров во временную таблицу
ВЫБРАТЬ
Т.Ссылка
ПОМЕСТИТЬ ВТ_Товары
ИЗ
Справочник.Номенклатура КАК Т
ГДЕ
Т.Ссылка В (&СписокТоваров);
// Шаг 2: Используем отбор внутри параметров виртуальной таблицы
ВЫБРАТЬ
...
ИЗ
ВТ_Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки( ,
Номенклатура В (ВЫБРАТЬ Ссылка ИЗ ВТ_Товары)
) КАК Остатки
ПО Товары.Ссылка = Остатки.Номенклатура
Это критически важно при использовании RLS. Чем проще и "атомарнее" запросы, тем меньше шансов, что SQL Server выберет неверный план.
Еще одна причина, по которой отчеты могут вести себя непредсказуемо, — это устаревшая статистика (Statistics) на SQL Server или проблемы с базой tempdb.
Статистика: Если отчет активно использует временные таблицы, и в них записывается большое количество данных, SQL Server может не успеть обновить статистику. Он будет "думать", что во временной таблице 1 строка, хотя там их 100 000. В результате — неверный выбор типа соединения (Join) и медленная работа.
Фоновая нагрузка: Проверьте, не запускаются ли в момент "тормозов" регламентные задания (например, обновление полнотекстового индекса, обмен данными или резервное копирование). Даже если отчет только читает данные, высокая нагрузка на диск или процессор сервера (особенно при схеме питания "Сбалансированная" вместо "Высокая производительность") может замедлить выполнение сложных выборок.
Давайте систематизируем шаги, которые нужно предпринять для исправления ситуации.
Настройте технологический журнал для сбора событий TTIMEOUT, TLOCK и долгих запросов. Это покажет, на чем именно висит система: на ожидании ресурсов или на выполнении самого запроса.
Разбейте большую "простыню" запроса на последовательные пакеты с использованием менеджера временных таблиц. Избегайте соединений "всего со всем" в одном запросе. Уберите обращения "через точку" к полям составного типа (например, Документ.Партнер.ОсновнойМенеджер), так как при RLS это вызывает неявные тяжелые соединения.
Если проблема подтвердится (сброс кэша процедур DBCC FREEPROCCACHE на SQL сервере временно "лечит" отчет), можно попробовать использовать в запросах конструкцию, заставляющую SQL перекомпилировать план, но в языке запросов 1С это не всегда доступно напрямую.
Более надежный способ в рамках 1С: если отчет сложный и с RLS, вынесите выборку данных в Привилегированный модуль. В этом случае:
Это кардинально снижает нагрузку на SQL Server, так как ему не нужно проверять права доступа для каждой строки в сложных соединениях.
Проблема "то быстро, то медленно" почти всегда кроется на стыке работы оптимизатора СУБД и механизма RLS платформы 1С. Ваша задача — максимально упростить жизнь оптимизатору: использовать РАЗРЕШЕННЫЕ, разбивать сложные запросы на простые этапы через временные таблицы и следить за актуальностью статистики на сервере СУБД.