При сверке или интеграции данных между двумя базами 1С часто используется COM-соединение. Однако при обработке больших массивов данных разработчики сталкиваются с сильным падением производительности. Замер времени показывает, что наибольшие задержки происходят на этапе получения уникальных идентификаторов (GUID) ссылочных объектов. Разберем, почему возникает эта проблема и как существенно ускорить выполнение выгрузки.
Основной источник задержек при работе через COM-соединение — это накладные расходы на межпроцессное взаимодействие (маршалинг данных). Каждое обращение к методам или свойствам объекта подключенной базы через COM-клиент заставляет платформу выполнять отдельный сетевой или межпроцессный вызов.
Рассмотрим стандартный, но медленный вариант получения строкового GUID:
ГУИД = COMПодключение.XMLСтрока(COMОбъект.УникальныйИдентификатор());
В этой строке выполняется сразу несколько последовательных операций:
УникальныйИдентификатор().XMLСтрока() для преобразования полученного идентификатора в строку.Если выполнять эти действия в цикле для тысяч элементов, суммарное время ожидания вызовов становится критическим.
Проанализируем работу платформы с функцией XMLСтрока(). Если в подключаемой базе обрабатывается объект ссылочного типа (например, СправочникСсылка.Номенклатура или ДокументСсылка.РеализацияТоваровУслуг), нет необходимости предварительно вызывать метод УникальныйИдентификатор().
Функция XMLСтрока() умеет принимать саму ссылку и автоматически преобразовывать её в строковое представление GUID на стороне подключаемой базы за один вызов:
// Оптимизированное получение строкового GUID
ГУИД = COMПодключение.XMLСтрока(COMОбъект);
Преимущество метода: мы сокращаем количество межпроцессных вызовов ровно в два раза для каждой записи, что дает ощутимый прирост скорости при обходе больших выборок.
Чтобы максимально сократить накладные расходы, необходимо стремиться к правилу: минимизировать количество вызовов через границу COM. Вместо обхода выборки в цикле на стороне базы-приемника выгодно сформировать всю необходимую структуру данных внутри подключаемой базы, сериализовать её и передать единым массивом или строкой.
Рассмотрим пример, когда на стороне внешнего соединения формируется массив GUID или таблица соответствий, которая затем передается целиком:
// Выполняем код на стороне подключаемой базы (Б2)
ТаблицаРезультат = COMПодключение.NewObject("ТаблицаЗначений");
// Выполняем запрос в Б2 и заполняем данные...
// Сериализуем данные или собираем их в массив на стороне Б2
МассивГуидов = COMПодключение.NewObject("Массив");
Для Каждого СтрИз Выборка Цикл
МассивГуидов.Добавить(COMПодключение.XMLСтрока(СтрИз.Ссылка));
КонецЦикла;
Еще более эффективный подход — вызвать экспортную функцию общего модуля в подключаемой базе, которая сама выполнит запрос, сформирует JSON или единую строку и вернет результат. В этом случае происходит всего один COM-вызов за всю операцию сверки.
Если базы работают на платформе 1С:Предприятие версии 8.3.22 и выше, в языке запросов доступна встроенная функция УникальныйИдентификатор(). Это позволяет извлекать GUID объектов непосредственно в результате выполнения запроса в подключаемой базе:
Запрос = COMПодключение.NewObject("Запрос");
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| УНИКАЛЬНЫЙИДЕНТИФИКАТОР(Номенклатура.Ссылка) КАК Идентификатор
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Идентификатор уже получен на стороне СУБД в виде строки/GUID
ГУИД = Выборка.Идентификатор;
КонецЦикла;
Если сверка объектов выполняется регулярно, целесообразно настроить кэширование GUID. Посмотрим на этот архитектурный подход:
РегистрСведений.Если оптимизация COM-соединения не дает требуемой скорости из-за ограничений инфраструктуры, стоит рассмотреть переход на современные протоколы взаимодействия: