В практике поддержки конфигураций "1С:Управление Торговлей 11" (а также ERP и КА) нередко возникают ситуации, когда система начинает "тормозить" на ровном месте. Одной из распространенных и неприятных проблем является зависание интерфейса при попытке выбрать значение в поле ввода. Рассмотрим конкретный кейс: пользователь (не администратор) пытается изменить вид цены в табличной части "Заказа клиента", и система "зависает" на 5-10 секунд. При этом под полными правами все работает мгновенно.
Разберем подробно причины этого поведения, методы диагностики и способы решения проблемы, объединяя опыт сообщества и технические особенности платформы 1С.
Ситуация выглядит следующим образом:
Первым шагом всегда должен быть замер производительности. Запустим его в конфигураторе и выполним действие, вызывающее торможение. В данном случае анализ замера приводит нас в модуль менеджера справочника ВидыЦен, в процедуру обработки получения данных выбора.
Виновником оказывается строка кода, которая пытается загрузить список доступных видов цен:
ДанныеВыбора.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ВидЦен"));
Именно здесь, в момент выполнения запроса, система тратит драгоценные секунды.
Давайте посмотрим на запрос, который выполняется в этот момент. Он содержится в типовом коде конфигурации. Его задача — отобрать виды цен, доступные пользователю, с учетом множества условий (индивидуальные виды цен для партнеров, соглашений, складов и т.д.).
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ВидыЦен.Ссылка КАК ВидЦен,
ВЫБОР
КОГДА НЕ Партнеры.Ссылка ЕСТЬ NULL
ТОГДА Партнеры.Ссылка
КОГДА НЕ СоглашенияСКлиентами.Ссылка ЕСТЬ NULL
ТОГДА СоглашенияСКлиентами.Ссылка
...
КОНЕЦ КАК ВладелецИндивидуальногоВидаЦен
ИЗ
Справочник.ВидыЦен КАК ВидыЦен
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Партнеры КАК Партнеры
ПО (ВидыЦен.Назначение = ЗНАЧЕНИЕ(Перечисление.НазначенияВидовЦен.ИндивидуальныйДляПартнера))
И (Партнеры.ИндивидуальныйВидЦены = ВидыЦен.Ссылка)
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СоглашенияСКлиентами КАК СоглашенияСКлиентами
ПО (ВидыЦен.Назначение = ЗНАЧЕНИЕ(Перечисление.НазначенияВидовЦен.ИндивидуальныйДляСоглашения))
И ВидыЦен.Ссылка = СоглашенияСКлиентами.ИндивидуальныйВидЦены
...
ГДЕ
ВидыЦен.ПометкаУдаления = ЛОЖЬ
...
Почему этот запрос работает медленно?
Ключевая проблема кроется в сочетании слова РАЗРЕШЕННЫЕ и сложной структуры соединений (LEFT JOIN).
РАЗРЕШЕННЫЕ, платформа 1С на уровне СУБД (SQL Server) добавляет к запросу дополнительные условия проверки прав доступа. В УТ 11 права доступа к справочникам Партнеры и СоглашенияСКлиентами — одни из самых сложных.ИндивидуальныйВидЦены.Рассмотрим действия, которые помогут устранить или минимизировать задержку.
Поскольку проблема часто возникает "внезапно" или после массовых изменений данных, первым делом стоит актуализировать статистику на сервере СУБД. Платформа 1С опирается на то, что SQL Server построит оптимальный план запроса. Неактуальная статистика может привести к чудовищному падению производительности именно в запросах с RLS.
Обратитесь к администратору баз данных для выполнения регламентных процедур (Update Statistics) для таблиц:
Справочник.ВидыЦенСправочник.ПартнерыСправочник.СоглашенияСКлиентамиВ современных версиях конфигураций (УТ 11, ERP) существует два режима работы RLS:
Перейдите в раздел НСИ и администрирование — Настройка пользователей и прав. Если у вас не включен "Производительный режим", стоит запланировать переход на него. Это потребует длительной обработки обновления прав (лучше делать в нерабочее время), но существенно ускорит работу списков и подборов.
Если административные меры не помогли, необходимо вмешательство в код. Чтобы убедиться, что проблема именно в соединении таблиц, можно воспользоваться методом исключения:
Создайте внешнюю обработку или тестовый отчет с текстом проблемного запроса. Запустите его под "тормозящим" пользователем. Поочередно комментируйте блоки ЛЕВОЕ СОЕДИНЕНИЕ. Обычно "узким местом" является соединение с таблицей Партнеры или СоглашенияСКлиентами.
Поскольку менять типовой код модуля менеджера — плохая практика (затрудняет обновления), создадим расширение.
Вариант А: Использование привилегированного режима
Если бизнес-логика вашей компании допускает, что пользователь может видеть список видов цен без детальной проверки прав на владельцев (партнеров), можно обернуть выполнение запроса в привилегированный режим. В расширении перехватываем процедуру ОбработкаПолученияДанныхВыбора (или вызываемую из неё функцию получения списка) и устанавливаем режим:
УстановитьПривилегированныйРежим(Истина);
// Выполнение запроса получения видов цен
// ...
УстановитьПривилегированныйРежим(Ложь);
Это отключит проверку RLS (и ключевое слово РАЗРЕШЕННЫЕ станет неактуальным для проверки прав), и запрос выполнится мгновенно, как у администратора.
Вариант Б: Упрощение запроса
Если вы выяснили, что тормозит конкретное соединение (например, с таблицей складов или форматов магазинов), которое в вашем учете не используется или не критично для данного выбора, можно в расширении переопределить текст запроса, убрав лишние LEFT JOIN.
// Пример упрощенного запроса в расширении
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ВидыЦен.Ссылка КАК ВидЦен
|ИЗ
| Справочник.ВидыЦен КАК ВидыЦен
|ГДЕ
| ВидыЦен.ПометкаУдаления = ЛОЖЬ
| И ВидыЦен.ИспользоватьПриПродаже = &ИспользоватьПриПродаже";
// Обратите внимание: мы убрали соединения, если нам не нужно фильтровать
// по владельцу индивидуального вида цен в этом конкретном месте.
Задержка выбора вида цены — это классическая проблема производительности RLS на сложных запросах. Решение следует искать в таком порядке: