Почему возникает задержка при выборе вида цен в заказе клиента в УТ 11.5 и как это исправить?

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

В практике поддержки конфигураций "1С:Управление Торговлей 11" (а также ERP и КА) нередко возникают ситуации, когда система начинает "тормозить" на ровном месте. Одной из распространенных и неприятных проблем является зависание интерфейса при попытке выбрать значение в поле ввода. Рассмотрим конкретный кейс: пользователь (не администратор) пытается изменить вид цены в табличной части "Заказа клиента", и система "зависает" на 5-10 секунд. При этом под полными правами все работает мгновенно.

Разберем подробно причины этого поведения, методы диагностики и способы решения проблемы, объединяя опыт сообщества и технические особенности платформы 1С.

1. Симптомы и предварительная диагностика

Ситуация выглядит следующим образом:

  1. В документе Заказ клиента при клике на поле выбора Вида цены (или при начале ввода текста) происходит длительная задержка.
  2. Если открывать форму подбора (список выбора), задержки может не быть или она минимальна.
  3. Под пользователем с полными правами (Администратор) проблема не воспроизводится.
  4. Проблема может появиться внезапно, например, после обновления конфигурации, массового изменения данных (партнеров, соглашений) или добавления новых условий скидок.

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

Виновником оказывается строка кода, которая пытается загрузить список доступных видов цен:


ДанныеВыбора.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ВидЦен"));

Именно здесь, в момент выполнения запроса, система тратит драгоценные секунды.

2. Анализ "тяжелого" запроса

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


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ВидыЦен.Ссылка КАК ВидЦен,
    ВЫБОР
        КОГДА НЕ Партнеры.Ссылка ЕСТЬ NULL
            ТОГДА Партнеры.Ссылка
        КОГДА НЕ СоглашенияСКлиентами.Ссылка ЕСТЬ NULL
            ТОГДА СоглашенияСКлиентами.Ссылка
        ...
    КОНЕЦ КАК ВладелецИндивидуальногоВидаЦен
ИЗ
    Справочник.ВидыЦен КАК ВидыЦен
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Партнеры КАК Партнеры
        ПО (ВидыЦен.Назначение = ЗНАЧЕНИЕ(Перечисление.НазначенияВидовЦен.ИндивидуальныйДляПартнера))
        И (Партнеры.ИндивидуальныйВидЦены = ВидыЦен.Ссылка)
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СоглашенияСКлиентами КАК СоглашенияСКлиентами
        ПО (ВидыЦен.Назначение = ЗНАЧЕНИЕ(Перечисление.НазначенияВидовЦен.ИндивидуальныйДляСоглашения))
        И ВидыЦен.Ссылка = СоглашенияСКлиентами.ИндивидуальныйВидЦены
        ...
ГДЕ
    ВидыЦен.ПометкаУдаления = ЛОЖЬ
    ...

Почему этот запрос работает медленно?

Ключевая проблема кроется в сочетании слова РАЗРЕШЕННЫЕ и сложной структуры соединений (LEFT JOIN).

  1. Механизм RLS (Record Level Security): Когда обычный пользователь выполняет запрос со словом РАЗРЕШЕННЫЕ, платформа 1С на уровне СУБД (SQL Server) добавляет к запросу дополнительные условия проверки прав доступа. В УТ 11 права доступа к справочникам Партнеры и СоглашенияСКлиентами — одни из самых сложных.
  2. Левые соединения: Запрос пытается соединить таблицу видов цен с таблицами партнеров и соглашений, чтобы выяснить владельца индивидуального вида цены. При этом соединение идет по полю ИндивидуальныйВидЦены.
  3. Отсутствие индексов и устаревшая статистика: Если статистика SQL устарела (например, после массовой загрузки данных), планировщик запросов SQL может выбрать неоптимальный план выполнения. Он может решить сканировать всю таблицу партнеров (Table Scan) вместо использования индекса, попутно проверяя RLS для каждой записи.

3. Пошаговое решение проблемы

Рассмотрим действия, которые помогут устранить или минимизировать задержку.

Шаг 1. Обновление статистики SQL

Поскольку проблема часто возникает "внезапно" или после массовых изменений данных, первым делом стоит актуализировать статистику на сервере СУБД. Платформа 1С опирается на то, что SQL Server построит оптимальный план запроса. Неактуальная статистика может привести к чудовищному падению производительности именно в запросах с RLS.

Обратитесь к администратору баз данных для выполнения регламентных процедур (Update Statistics) для таблиц:

Шаг 2. Проверка режима RLS

В современных версиях конфигураций (УТ 11, ERP) существует два режима работы RLS:

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

Перейдите в раздел НСИ и администрирование — Настройка пользователей и прав. Если у вас не включен "Производительный режим", стоит запланировать переход на него. Это потребует длительной обработки обновления прав (лучше делать в нерабочее время), но существенно ускорит работу списков и подборов.

Шаг 3. Локализация проблемы в коде (для разработчиков)

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

Создайте внешнюю обработку или тестовый отчет с текстом проблемного запроса. Запустите его под "тормозящим" пользователем. Поочередно комментируйте блоки ЛЕВОЕ СОЕДИНЕНИЕ. Обычно "узким местом" является соединение с таблицей Партнеры или СоглашенияСКлиентами.

Шаг 4. Оптимизация через Расширение конфигурации

Поскольку менять типовой код модуля менеджера — плохая практика (затрудняет обновления), создадим расширение.

Вариант А: Использование привилегированного режима

Если бизнес-логика вашей компании допускает, что пользователь может видеть список видов цен без детальной проверки прав на владельцев (партнеров), можно обернуть выполнение запроса в привилегированный режим. В расширении перехватываем процедуру ОбработкаПолученияДанныхВыбора (или вызываемую из неё функцию получения списка) и устанавливаем режим:


УстановитьПривилегированныйРежим(Истина);
// Выполнение запроса получения видов цен
// ...
УстановитьПривилегированныйРежим(Ложь);

Это отключит проверку RLS (и ключевое слово РАЗРЕШЕННЫЕ станет неактуальным для проверки прав), и запрос выполнится мгновенно, как у администратора.

Вариант Б: Упрощение запроса

Если вы выяснили, что тормозит конкретное соединение (например, с таблицей складов или форматов магазинов), которое в вашем учете не используется или не критично для данного выбора, можно в расширении переопределить текст запроса, убрав лишние LEFT JOIN.


// Пример упрощенного запроса в расширении
Запрос.Текст = 
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
|	ВидыЦен.Ссылка КАК ВидЦен
|ИЗ
|	Справочник.ВидыЦен КАК ВидыЦен
|ГДЕ
|	ВидыЦен.ПометкаУдаления = ЛОЖЬ
|	И ВидыЦен.ИспользоватьПриПродаже = &ИспользоватьПриПродаже"; 
// Обратите внимание: мы убрали соединения, если нам не нужно фильтровать 
// по владельцу индивидуального вида цен в этом конкретном месте.

Резюме

Задержка выбора вида цены — это классическая проблема производительности RLS на сложных запросах. Решение следует искать в таком порядке:

  1. Обновить статистику SQL (самое быстрое и безопасное).
  2. Проверить и включить "Производительный режим" RLS.
  3. Использовать расширение для выполнения запроса в привилегированном режиме, если это допустимо с точки зрения безопасности данных.
← На главную