Как найти исходный запрос в конфигурации 1С по тексту SQL-запроса из СУБД?

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

В процессе администрирования крупной базы данных на платформе 1С Предприятие администраторы СУБД (MS SQL Server, PostgreSQL) часто сталкиваются с запросами, которые вызывают критическую нагрузку на процессор или дисковую подсистему. Мы видим «монструозный» SQL-текст, выполняющийся несколько минут, но как понять, какая именно строчка кода в конфигурации 1С породила этот кошмар?

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

Метод 1. Использование встроенной функции декодирования метаданных

Если перед вами текст SQL-запроса с именами таблиц вида _Reference45 или _Document220, первым делом необходимо сопоставить их с реальными объектами конфигурации 1С. Для этого мы можем использовать штатный механизм платформы.

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


ТаблицаСтруктуры = ПолучитьСтруктуруХраненияБазыДанных();
ИскомаяТаблицаСУБД = "_InfoRg134"; // Укажите имя таблицы из SQL-запроса

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

После того как мы выяснили, какие объекты 1С задействованы в СУБД-запросе, мы можем запустить глобальный поиск по конфигурации (комбинация клавиш Ctrl + Shift + F), используя имена найденных объектов (например, РегистрСведений.ЦеныНоменклатуры). Чтобы сузить область поиска, ищите места совместного соединения этих таблиц.

Метод 2. Поиск через Технологический журнал (ТЖ) 1С

Этот способ является самым надежным и точным, так как он позволяет получить не просто имя объекта 1С, а точный стек вызовов (контекст) встроенного языка вплоть до номера строки в модуле, где был вызван метод Выполнить().

Разберем по шагам, как настроить сбор логов для локализации конкретного запроса:

  1. Создайте или отредактируйте файл конфигурации технологического журнала logcfg.xml (он должен находиться в каталоге C:\Program Files\1cv8\conf\ для Windows-сервера).
  2. Настройте сбор событий работы с СУБД (например, DBMSSQL для MS SQL Server или DBPOSTGRS для PostgreSQL).
  3. Для того чтобы не писать гигабайты лишних логов, настройте жесткий фильтр по именам таблиц, которые вы обнаружили в тяжелом SQL-запросе.

Применим следующий шаблон конфигурации logcfg.xml:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-journal">
    <log location="C:\v8logs\heavy_queries" history="2">
        <event>
            <eq property="Name" value="DBMSSQL"/>
            <like property="Sql" value="%Reference12%"/>
            <like property="Sql" value="%InfoRg134%"/>
            <like property="Sql" value="%Document254%"/>
        </event>
        <property name="all"/>
    </log>
</config>

Проанализируем работу этого фильтра. Как только платформа 1С выполнит запрос к СУБД, в котором одновременно будут задействованы таблицы справочника 12, регистра сведений 134 и документа 254, данное событие запишется в лог. В логе нас будет интересовать свойство Context. Оно выглядит примерно так:


Context=ОбщийМодуль.ПроведениеСервер.Модуль : 124 : ДокументОбъект.ВыполнитьЗапрос()

Это дает нам стопроцентное понимание того, где именно в конфигурации находится проблемный код.

Метод 3. Оперативное сопоставление через консоль кластера

Что делать, если тяжелый запрос выполняется прямо сейчас и "вешает" рабочую базу, а времени на настройку технологического журнала нет? Выясним причину на лету с помощью СУБД и консоли администрирования 1С:

  1. Откройте SQL Server Management Studio (SSMS) и выполните запрос к системным представлениям для поиска активных долгих процессов:
    
    SELECT r.session_id, r.status, r.cpu_time, r.total_elapsed_time, t.text 
    FROM sys.dm_exec_requests r 
    CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t 
    WHERE r.session_id > 50;
    
  2. Найдите строку с вашим тяжелым запросом и запишите значение колонки session_id (это уникальный идентификатор сессии в СУБД, также известный как SPID).
  3. Откройте Консоль администрирования кластера 1С, перейдите в ветку вашей базы данных и откройте список Сеансы.
  4. Найдите колонку Номер соединения с СУБД (или "Идентификатор сессии СУБД" в зависимости от версии платформы) и найдите строчку, соответствующую вашему session_id.

Таким образом, вы мгновенно определите, какой именно пользователь запустил этот запрос, какой компьютер он использует и какое приложение (например, фоновое задание или конкретный отчет) сейчас перегружает систему.

Специфика анализа сложных SQL-запросов 1С

Проанализируем ситуации, при которых сопоставление может вызвать трудности, и выделим важные правила:

Используя предложенные методы совместно, вы сможете оперативно локализовать любые проблемные запросы и оптимизировать работу вашей системы 1С.

← На главную