В процессе мониторинга производительности СУБД разработчики и администраторы нередко сталкиваются с ситуацией, когда одиночный SQL-запрос к базе данных выполняется сотни тысяч раз в минуту. Рассмотрим, как расшифровать структуру такого запроса, сопоставить внутреннее имя таблицы SQL с объектом метаданных 1С и устранить причину высокой нагрузки.
Платформа 1С использует внутренние идентификаторы для таблиц и полей в реляционной базе данных. Префикс _InfoRg указывает на то, что таблица принадлежит непериодическому регистру сведений. Чтобы узнать, какой именно регистр скрывается за системным именем, воспользуемся встроенной функцией платформы.
Разберем по шагам, как получить понятное имя объекта 1С:
ПолучитьСтруктуруХраненияБазыДанных(), которая возвращает таблицу соответствия между метаданными конфигурации и таблицами в базе данных SQL.Посмотрим на пример программного поиска регистра и его полей:
ТаблицаХранения = ПолучитьСтруктуруХраненияБазыДанных();
Отбор = Новый Структура("ИмяТаблицыХранения", "_InfoRg23289");
НайденныеСтроки = ТаблицаХранения.НайтиСтроки(Отбор);
Для Каждого СтрокаТаблицы Из НайденныеСтроки Цикл
Сообщить("Объект метаданных: " + СтрокаТаблицы.Имя);
Сообщить("Назначение: " + СтрокаТаблицы.Метаданные);
// Переберем поля таблицы для расшифровки измерений и ресурсов
Для Каждого Поле Из СтрокаТаблицы.Поля Цикл
Если Поле.ИмяПоляХранения = "_Fld23293" Тогда
Сообщить("Поле _Fld23293 соответствует реквизиту/ресурсу: " + Поле.Имя);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Проанализируем структуру текста запроса, вызывающего повышенную нагрузку:
Запрос осуществляет выборку значения одного поля (_Fld23293) с отбором по ключевым измерениям (_Fld23290RRef, _Fld23291, _Fld23292). Наличие составного условия вида _TYPE, _S, _RRRef указывает на то, что одно из измерений регистра имеет составной тип данных (ссылка на несколько видов объектов или строка/число).
Частота выполнения в 130 000 вызовов в минуту однозначно сигнализирует о паттерне N+1 запросов, когда операция чтения одиночной записи выполняется в цикле вместо пакетной обработки данных.
Выясним причину высокой частоты выполнения запросов с помощью следующих инструментов:
DBMSSQL с фильтром по тексту запроса и обязательным сбором свойства Context. Это позволит увидеть точный стек вызовов на встроенном языке 1С.РегистрыСведений[Имя].Получить() или СоздатьКлючЗаписи().Прочитать().ПриПолученииДанныхНаСервере или вызовы серверных функций в условном оформлении.Рассмотрим подробнее варианты исправления кода в зависимости от выявленного источника:
ГДЕ Измерение В (&МассивЗначений) или с левым соединением временной таблицы.Соответствие или используем общий модуль с признаком Повторное использование возвращаемых значений.ЛЕВОЕ СОЕДИНЕНИЕ непосредственно в текст основного запроса динамического списка, исключив ручное заполнение колонок построчно.