Как определить объект 1С по SQL-запросу и оптимизировать частоту его вызовов

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе мониторинга производительности СУБД разработчики и администраторы нередко сталкиваются с ситуацией, когда одиночный SQL-запрос к базе данных выполняется сотни тысяч раз в минуту. Рассмотрим, как расшифровать структуру такого запроса, сопоставить внутреннее имя таблицы SQL с объектом метаданных 1С и устранить причину высокой нагрузки.

Определение объекта метаданных по имени таблицы СУБД

Платформа 1С использует внутренние идентификаторы для таблиц и полей в реляционной базе данных. Префикс _InfoRg указывает на то, что таблица принадлежит непериодическому регистру сведений. Чтобы узнать, какой именно регистр скрывается за системным именем, воспользуемся встроенной функцией платформы.

Разберем по шагам, как получить понятное имя объекта 1С:

  1. Откроем внешнюю обработку или запустим обработку в режиме предприятия с возможностью выполнения произвольного программного кода.
  2. Вызовем функцию ПолучитьСтруктуруХраненияБазыДанных(), которая возвращает таблицу соответствия между метаданными конфигурации и таблицами в базе данных SQL.
  3. Выполним поиск нужной таблицы по ее физическому имени в базе.

Посмотрим на пример программного поиска регистра и его полей:


ТаблицаХранения = ПолучитьСтруктуруХраненияБазыДанных();
Отбор = Новый Структура("ИмяТаблицыХранения", "_InfoRg23289");
НайденныеСтроки = ТаблицаХранения.НайтиСтроки(Отбор);

Для Каждого СтрокаТаблицы Из НайденныеСтроки Цикл
    Сообщить("Объект метаданных: " + СтрокаТаблицы.Имя);
    Сообщить("Назначение: " + СтрокаТаблицы.Метаданные);
    
    // Переберем поля таблицы для расшифровки измерений и ресурсов
    Для Каждого Поле Из СтрокаТаблицы.Поля Цикл
        Если Поле.ИмяПоляХранения = "_Fld23293" Тогда
            Сообщить("Поле _Fld23293 соответствует реквизиту/ресурсу: " + Поле.Имя);
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

Анализ структуры SQL-запроса

Проанализируем структуру текста запроса, вызывающего повышенную нагрузку:

Запрос осуществляет выборку значения одного поля (_Fld23293) с отбором по ключевым измерениям (_Fld23290RRef, _Fld23291, _Fld23292). Наличие составного условия вида _TYPE, _S, _RRRef указывает на то, что одно из измерений регистра имеет составной тип данных (ссылка на несколько видов объектов или строка/число).

Частота выполнения в 130 000 вызовов в минуту однозначно сигнализирует о паттерне N+1 запросов, когда операция чтения одиночной записи выполняется в цикле вместо пакетной обработки данных.

Поиск источника проблемы в кодовой базе

Выясним причину высокой частоты выполнения запросов с помощью следующих инструментов:

  1. Настройка технологического журнала: настроим сбор событий DBMSSQL с фильтром по тексту запроса и обязательным сбором свойства Context. Это позволит увидеть точный стек вызовов на встроенном языке 1С.
  2. Замер производительности: запустим стандартный инструмент замера в конфигураторе и воспроизведем сценарий работы пользователей. Обратим внимание на количество вызовов методов РегистрыСведений[Имя].Получить() или СоздатьКлючЗаписи().Прочитать().
  3. Проверка динамических списков: проверим обработчики событий формы, такие как ПриПолученииДанныхНаСервере или вызовы серверных функций в условном оформлении.

Способы оптимизации и устранения нагрузки

Рассмотрим подробнее варианты исправления кода в зависимости от выявленного источника:

  1. Замена циклического чтения пакетным запросом: если получение данных из регистра происходит внутри цикла обхода строк документа или таблицы значений, перепишем алгоритм на один запрос с конструкцией ГДЕ Измерение В (&МассивЗначений) или с левым соединением временной таблицы.
  2. Кэширование редко меняющихся данных: если регистр хранит условно-постоянную информацию (настройки, учетную политику, соответствия), выгрузим данные перед началом массовой обработки в объект Соответствие или используем общий модуль с признаком Повторное использование возвращаемых значений.
  3. Перенос вычислений в запрос динамического списка: если данные регистра требуются для отображения в форме списка, добавим связь с регистром через ЛЕВОЕ СОЕДИНЕНИЕ непосредственно в текст основного запроса динамического списка, исключив ручное заполнение колонок построчно.
  4. Проверка индексов: убедимся, что порядок измерений в метаданных регистра 1С совпадает с полями фильтрации в запросе, чтобы СУБД эффективно использовала индексный поиск.
← На главную