Одной из самых сложных задач для разработчика и администратора 1С является поиск причин деградации производительности системы. Когда пользователи жалуются на то, что "всё тормозит", нам необходимо выполнить замер производительности контура 1С и поиск узких мест, чтобы точно определить: какой именно запрос, в какой строке кода и почему выполняется долго. Для решения этой задачи мы воспользуемся встроенным инструментом платформы — Технологическим журналом (ТЖ). В этой статье мы подробно разберем, как правильно сконфигурировать ТЖ, чтобы выявить "тяжелые" запросы к базе данных, и как интерпретировать полученные результаты.
Для того чтобы система начала фиксировать события, нам необходимо создать файл конфигурации logcfg.xml. Рассмотрим ситуацию, когда сервер 1С:Предприятие установлен на Windows. В этом случае файл должен располагаться в папке C:\Program Files\1cv8\conf. Если папки или файла не существует, их необходимо создать вручную. Разберем структуру этого файла, ориентированную на поиск медленных запросов к СУБД.
Проанализируем пример содержимого logcfg.xml, который позволяет записывать события длительностью более 1 секунды (1000 миллисекунд):
<config xmlns="http://v8.1c.ru/7.4/config/log">
<log location="C:\LOGS\SQL_SLOW" history="24">
<event>
<eq property="Name" value="DBMSSQL"/>
<gt property="Duration" value="1000000"/>
</event>
<event>
<eq property="Name" value="SDBL"/>
<gt property="Duration" value="1000000"/>
</event>
<property name="All"/>
</log>
</config>
Разберем основные параметры этого файла по шагам:
location указывает путь, куда будут сохраняться логи. Убедимся, что у пользователя, под которым запущена служба ragent, есть права на запись в эту папку.history определяет время хранения логов в часах. В нашем примере это 24 часа.DBMSSQL отвечает за прямые запросы платформы к Microsoft SQL Server (это позволяет более детально анализировать SQL сервер глазами 1С-ника).SDBL фиксирует запросы на внутреннем языке запросов платформы 1С.Duration измеряется в микросекундах (1 секунда = 1 000 000 мкс). Мы установили фильтр, чтобы отсечь быстрые операции и не перегружать дисковую подсистему лишними записями.После сохранения файла logcfg.xml платформа автоматически (без перезагрузки сервера) начнет записывать события. Перейдем в папку C:\LOGS\SQL_SLOW и попробуем проанализировать структуру лога. Для удобства работы с большими объемами данных может потребоваться конвертер технологического журнала в новый формат или даже экспорт технологического журнала 1С в Elastic с помощью Logstash. Каждая запись содержит метку времени, длительность, имя события и набор свойств (при автоматическом разборе иногда мы программно убираем лишние переносы строк для целостности записей).
Выясним причину долгого выполнения, обратив внимание на свойство Context. Именно оно указывает на конкретную строку программного кода 1С, которая инициировала тяжелый запрос. Рассмотрим типичный пример записи в логе:
24:15.123001-1500000,DBMSSQL,4,
Context='Обработка.ПроведениеДокументов.МодульОбъекта : 150 : Движения.Записать();',
Sql='SELECT * FROM _InfoRg123 WHERE _Fld456 = ?',
RowsAffected=100000
Посмотрим на этот пример внимательнее. Мы видим, что операция записи набора записей регистра сведений заняла 1,5 секунды (1500000 микросекунд). Поле Context четко указывает, что проблема возникла в 150-й строке модуля объекта обработки. Это позволяет нам сразу перейти к оптимизации конкретного участка кода.
Как только мы локализовали проблему, проанализируем возможные варианты оптимизации. Чаще всего причинами медленной работы являются:
Sql мы видим условие WHERE по полям, которые не входят в индекс, SQL Server будет вынужден сканировать всю таблицу (Table Scan).Context мы видим многократное обращение к базе данных внутри цикла, следует переписать код с использованием временных таблиц.Рассмотрим пример правильного подхода к выборке данных, который поможет избежать лишних блокировок и ускорить выполнение:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВтТовары
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ВидНоменклатуры = &Вид;
|
|ВЫБРАТЬ
| Остатки.Товар,
| Остатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, Товар В (ВЫБРАТЬ Ссылка ИЗ ВтТовары)) КАК Остатки";
Запрос.УстановитьПараметр("Вид", Справочники.ВидыНоменклатуры.Товар);
РезультатЗапроса = Запрос.Выполнить();
В данном примере мы сначала отфильтровали нужную номенклатуру во временную таблицу ВтТовары, а затем передали её в качестве фильтра в параметры виртуальной таблицы остатков. Это значительно эффективнее, чем накладывать условие ГДЕ на уже полученный результат виртуальной таблицы.
Важно помнить, что включенный Технологический журнал создает дополнительную нагрузку на сервер. Поэтому придерживаемся следующих правил:
Duration) или по конкретным пользователям (t:userName).history, чтобы старые файлы удалялись автоматически.logcfg.xml или переименуйте его (например, в _logcfg.xml), чтобы прекратить запись.Таким образом, использование Технологического журнала позволяет нам превратить догадки о причинах тормозов в точный инженерный расчет. Разберем ситуацию, проанализируем логи и внесем точечные изменения в код или структуру индексов, чтобы обеспечить максимально быструю работу системы 1С.