Устранение неявных обращений к базе данных через точку от ссылки в 1С
- Критическое замедление циклов обработки массивов объектов и табличных частей.
- Журнал регистрации и ТЖ переполнены тысячами мелких запросов вида
SELECT ... FROM _Reference123 WHERE _IDRRef = .... - Высокая утилизация сетевого стека между сервером 1С и СУБД.
1. Механизм скрытого разыменования ссылок в 1С
Когда разработчик обращается к реквизиту ссылки через точку (например, Ссылка.Контрагент.Город.Наименование), платформа 1С выполняет неявный синхронный SQL-запрос к СУБД для каждого уровня вложенности, считывая весь объект целиком в кэш.
2. Пример антипаттерна в цикле обработки
// ПЛОХО: 1000 строк = 2000 скрытых запросов к СУБД!
Для Каждого Стр Из ТабличнаяЧасть Цикл
СтавкаНДС = Стр.Номенклатура.СтавкаНДС;
Страна = Стр.Номенклатура.СтранаПроисхождения.Наименование;
КонецЦикла;3. Оптимизация: Пакетное считывание через один запрос
// ХОРОШО: 1 запрос ко всем данным за 2 миллисекунды
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ТЧ.Номенклатура КАК Номенклатура,
| ТЧ.Номенклатура.СтавкаНДС КАК СтавкаНДС,
| ТЧ.Номенклатура.СтранаПроисхождения.Наименование КАК СтранаНаименование
|ИЗ
| &ТЧ КАК ТЧ");
Запрос.УстановитьПараметр("ТЧ", ТабличнаяЧасть.Выгрузить());
Результат = Запрос.Выполнить().Выгрузить();
// Быстрое сопоставление в памяти по структуре или соответствию4. Использование функций БСП
Для единичных ссылок вне циклов используйте оптимизированную функцию БСП ОбщегоНазначения.ЗначенияРеквизитовОбъекта(), считывающую только запрошенные поля без чтения всего объекта.
Частые вопросы (FAQ)
Почему обращение через точку считывает все поля объекта, а не только запрошенное?
Платформа 1С считывает объект объектной модели целиком в память сеанса, чтобы закэшировать его. Если у объекта 100 реквизитов и табличные части, все они поднимаются в RAM.
Как найти неявные обращения через точку в коде конфигурации?
Используйте статические анализаторы кода (1C:Enterprise Development Tools / SonarQube с плагином BSL / 1С:АПК) или анализируйте события DBMSSQL с фильтром по контексту модуля.
Работает ли разыменование через точку в самом языке запросов 1С?
В языке запросов 1С обращение через точку транслируется оптимизатором в SQL LEFT JOIN, что является эффективным в отличие от объектного кода 1С++.
Чем заменить обращение к реквизитам шапки документа в модуле менеджера?
Передавайте структуру реквизитов, заранее сформированную одним запросом, вместо передачи одной ссылки на документ.