header_bg
Расследование причин медленной работы в информационной базе «1С:Предприятие»
Направление
Тестирование
Время прочтения
14 мин.
Количество просмотров
17

Расследование причин медленной работы в информационной базе «1С:Предприятие»

Введение: цели и ценность технологической экспертизы

Производительность корпоративной информационной системы — это не абстрактная техническая характеристика, а прямой экономический показатель. Когда пользователь ждёт завершения операции проведения документа более ста секунд, это означает не просто дискомфорт: это парализованный бизнес-процесс, накапливающаяся очередь необработанных операций и нарастающее недовольство персонала. Перемноженное на число пользователей системы и частоту операций, это превращается в измеримые потери рабочего времени и, как следствие, в рост совокупной стоимости владения (TCO).

Производительность корпоративной системы.png

Именно здесь технологическая экспертиза платформы «1С:Предприятие» приобретает самостоятельную бизнес-ценность, отличную от стандартного администрирования СУБД. Классический DBA — специалист по администрированию SQL Server или PostgreSQL — располагает мощными инструментами анализа: планы запросов, помощник создания индексов, статистика ожиданий. Однако он видит только ту часть картины, которую ему предъявляет СУБД. Платформа «1С:Предприятие» является посредником между прикладной логикой и базой данных: она самостоятельно генерирует SQL-запросы, управляет транзакциями, реализует собственный механизм блокировок и формирует соединения с сервером. Не зная этой механики, администратор СУБД рискует бесконечно оптимизировать индексы на таблицах, не понимая, что корень проблемы находится в архитектурном решении на уровне прикладного кода.

Цель технологической экспертизы — выстроить полную цепочку причинно-следственных связей: от жалобы пользователя через журнал событий платформы к конкретному SQL-запросу и, далее, к породившей его строке кода «1С:Предприятия» или архитектурному решению. Только такой сквозной анализ позволяет принять обоснованное техническое решение, дающее измеримый результат.

Данная статья описывает методологию подобного расследования и иллюстрирует её практическим кейсом из реального проекта на базе конфигурации «1С:ERP Горнодобывающая промышленность», в котором удалось локализовать причину длительных операций и описать путь к их устранению.

Анатомия проблемы: почему запросы «1С:Предприятия» работают медленно

Как платформа транслирует запросы

Разработчик на языке «1С:Предприятия» пишет запросы на встроенном языке запросов, синтаксически напоминающем язык SQL, но работающем с метаданными конфигурации через прикладные имена объектов: Документ.ПриобретениеТоваровУслуг, РегистрСведений.ЦеныНоменклатуры, ВЫБРАТЬ … ИЗ РегистрНакопления. ТоварыНаСкладах. Остатки(…). Платформа преобразует эти конструкции в реальный SQL запрос, подставляя физические имена таблиц базы данных вида _Document251, _InfoRg105575, _AccumRgT89012 — имена, генерируемые автоматически и зависящие от внутренних идентификаторов объектов метаданных.

Трансляция выполняется в процессе выполнения, и разработчик, как правило, не видит итогового SQL-текста в среде разработки. Это создаёт структурный разрыв: автор запроса на языке «1С:Предприятия» может не подозревать, какой именно план выполнения строит оптимизатор СУБД. Ряд конструкций языка «1С:Предприятия» транслируется в неэффективный SQL запрос предсказуемо — и именно знание этих закономерностей является ядром компетенции эксперта по технологическим вопросам.

Ключевые источники деградации производительности

Деградация производительности.jpg

Отсутствие или неоптимальность индексов. Платформа создаёт индексы на физических таблицах по своим правилам: обязательные индексы по первичным ключам, индексы по измерениям регистров при наличии соответствующих флагов в метаданных. Дополнительные индексы, необходимые для конкретных пользовательских запросов, разработчик должен проектировать осознанно. Временные таблицы, создаваемые в пакетных запросах через конструкцию ПОМЕСТИТЬ, по умолчанию не имеют индексов — если в дальнейшем к ним выполняется соединение по нескольким полям, планировщик вынужден использовать полное сканирование.

Виртуальные таблицы без ограничивающих параметров. Конструкции РегистрНакопления. ТоварыНаСкладах. Остатки() и РегистрСведений. ЦеныНоменклатуры. СрезПоследних() — это не просто синтаксические конструкции. Платформа разворачивает их во вложенные подзапросы с группировками и агрегацией по всем данным регистра. Если параметры фильтрации (дата среза, список измерений) не переданы в скобках, подзапрос охватывает всю историю регистра. Результатом становится многомиллионный промежуточный набор данных, который затем соединяется с основным запросом — типичная причина времени выполнения в десятки секунд.

Неявные преобразования типов. Поля составного типа (характерные для «1С:Предприятия», где одна колонка может хранить ссылку на любой из нескольких объектов метаданных) генерируют в SQL несколько физических колонок с суффиксами _TYPE, _ID, _RTRef, _RRRef. Сравнение такого поля со значением конкретного типа без явного приведения типа в запросе вынуждает планировщик применять сложные условия, часто исключающие использование индекса.

LIKE с ведущим подстановочным символом. Это один из наиболее коварных антипаттернов, потому что он может быть порождён не разработчиком напрямую, а самой платформой — в частности, механизмом поиска по строке в динамических списках. Условие LIKE '%строка%' с символом % в начале маски делает использование B-tree индекса невозможным: планировщик не может воспользоваться упорядоченностью индекса, поскольку не знает, с какого символа начинается искомое значение. Единственный путь — последовательное сканирование всей таблицы (Seq Scan / Full Table Scan).

LIKE.jpg

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

Инструментарий эксперта для расследования

Грамотный эксперт использует последовательный набор инструментов, каждый из которых покрывает свой уровень расследования проблемы.

Инструменты для расследования медленной работы 1С Предприятие.jpg

Подсистема «Оценка производительности» БСП

Библиотека стандартных подсистем (БСП) включает готовый инструмент замера производительности прикладного кода — подсистему «Оценка производительности». Она реализует расчёт индекса APDEX по накопленным замерам и не требует сторонних инструментов: всё необходимое уже встроено в типовые конфигурации на базе БСП (1С:ERP, 1С:УТ, 1С:Бухгалтерия и др.).

Механика работы строится вокруг понятия ключевой операции — именованного измеримого действия с заданным целевым временем выполнения (T). Например, проведение документа, формирование отчета или выполнение расчета себестоимости. Операция регистрируется в справочнике «Ключевые операции» либо явно через ОценкаПроизводительности. СоздатьКлючевыеОперации(), либо автоматически при первом замере. Разработчик «оборачивает» целевой участок кода двумя вызовами:

ВремяНачала = ОценкаПроизводительности. НачатьЗамерВремени();

// ... измеряемый код ...

ОценкаПроизводительности. ЗакончитьЗамерВремени(

    "Провести. ПриобретениеТоваровУслуг",

    ВремяНачала,

    Товары.Количество()  // «вес» замера — объём обработанных данных

);

Для длительных операций, выполняемых в фоновых заданиях, предусмотрен отдельный API:

ОписаниеЗамера = ОценкаПроизводительности. НачатьЗамерДлительнойОперации(

    "ФоновоеЗадание. РасчётСебестоимости");

// ... в цикле, по мере выполнения ...

ОценкаПроизводительности. Зафиксировать ЗамерДлительнойОперации(

    ОписаниеЗамера, 1, "ОбработкаДокумента");

ОценкаПроизводительности. ЗакончитьЗамерДлительнойОперации(

    ОписаниеЗамера, ИтогоДокументов, "РасчётЗавершён");

Результаты накапливаются в регистре сведений «Замеры». На их основе платформа рассчитывает APDEX по стандартной формуле следующим образом:

APDEX =  (Count_t  + Count_f/2)/Count_Total 

где:

T - целевое время выполнения целевой операции;

Countt  - количество операций, время выполнения которых не превышает время T;

Countf - количество операций, время ответа выполнения больше T, но меньше или равно 4T. Их ценность делится напополам (коэффициент 0.5);

CountTotal - общее количество зарегистрированных запросов за период.

Подсистема является точкой входа в расследование производительности: просматривая накопленные APDEX-оценки по ключевым операциям, эксперт выявляет операции-кандидаты для углублённого анализа — те, чей индекс опустился ниже 0,5, — и переходит к следующему уровню диагностики через технологический журнал.

Технологический журнал (ТЖ)

Технологический журнал — наиболее детальный источник диагностической информации платформы. Настраивается через файл logcfg.xml, который размещается в каталоге конфигурации кластера серверов. Для расследования производительности ключевыми являются следующие типы событий:

CALL — серверный вызов, фиксирует общую продолжительность обращения клиента к серверу с указанием контекста (имя метода, формы, модуля), а также значения Duration (полное время в микросекундах) и CpuTime (процессорное время). Разница между ними — время ожидания СУБД, сети или блокировок.

DBMSSQL / DBPOSTGRS — события выполнения конкретного SQL-запроса к СУБД (SQL Server и PostgreSQL соответственно). Содержат текст запроса, время выполнения, количество строк результата и план запроса (при настройке planSQLText=1).

EXCP — исключения платформы, полезны при диагностике ошибок в транзакциях.

TLOCK / TTIMEOUT / TDEADLOCK — события управляемых блокировок, незаменимы при расследовании конфликтов блокировок.

Типичная стратегия настройки ТЖ для расследования производительности — задать фильтр по длительности (Duration > 10000000, то есть более 10 секунд) и собирать события CALL и DBPOSTGRS/DBMSSQL. Это существенно снижает объём журнала и позволяет сосредоточиться на проблемных операциях.

Профайлеры СУБД

Для SQL Server это Extended Events (пришедшие на смену SQL Server Profiler): позволяют перехватывать запросы, превышающие заданный порог выполнения, с полным текстом и планом. Для PostgreSQL — расширение pg_stat_statements, которое накапливает статистику выполнения всех запросов с усреднёнными показателями времени, числа вызовов и количества считанных блоков. pg_stat_statements особенно ценно тем, что работает постоянно в фоне и не требует воспроизведения проблемы — аналитик получает исторические данные за период.

Встроенный замер производительности конфигуратора

Конфигуратор «1С:Предприятия» предоставляет инструмент замера производительности, который позволяет профилировать выполнение кода в разрезе строк модуля и видеть суммарное время, затраченное на каждую строку. Это инструмент для финального этапа расследования, когда подозреваемый код уже идентифицирован по данным ТЖ.

Методология расследования и практический кейс

Общий алгоритм расследования

Расследование проблем производительности в «1С:Предприятие» следует организовывать как нисходящий процесс сужения области поиска — от агрегированных метрик к конкретной строке кода или SQL-запросу. Алгоритм состоит из шести шагов.

Шаг 1. Идентификация проблемных операций через подсистему «Оценка производительности» БСП. Просматриваем накопленные замеры по ключевым операциям: отбираем те, у которых APDEX ниже порогового значения 0,5. Это даёт список кандидатов с указанием имени операции, числа замеров и диапазона времени выполнения.

Шаг 2. Сбор ТЖ по событиям CALL с фильтром по длительности. Для выявленных операций формируем срез событий CALL, сортируем по произведению средней длительности и числа вызовов (приоритет тем событиям, которые и долго выполняются, и часто встречаются).

Шаг 3. Анализ соотношения Duration/CpuTime. Это ключевой диагностический шаг. Если CpuTime << Duration, процессор большую часть времени простаивал — это признак ожидания внешнего ресурса: СУБД, сети или блокировки.

Шаг 4. Погружение в события DBPOSTGRS/DBMSSQL. По контексту проблемного CALL находим связанные события СУБД, изучаем текст запросов и их длительность.

Шаг 5. Анализ текста запроса и плана выполнения. Ищем характерные антипаттерны: полное сканирование, LIKE с ведущим %, Hash Join вместо Nested Loop на малых выборках, Sort на больших объёмах без индекса.

Шаг 6. Трассировка к коду «1С:Предприятие». По имени таблицы в запросе через метаданные конфигуратора (или инструменты поиска кода) идентифицируем объект метаданных и, далее, запрос в коде «1С:Предприятия», породивший данный SQL.

Практический кейс: медленное проведение документа «Приобретение товаров и услуг»

Рассмотрим расследование, проведённое в реальном проекте на конфигурации «1С:Горнодобывающая промышленность». Пользователи жаловались на медленное проведение документов «Приобретение товаров и услуг» и долгую работу с динамическими списками в журналах документов. 

Шаг 1. Картина в подсистеме «Оценка производительности»

Данные замеров, собранных подсистемой «Оценка производительности» БСП за исследуемый период, зафиксировали катастрофическую картину:

Метрика  Значение 
APDEX операции «Провести документ» 0,228
Минимальное время проведения 0,193 с
Максимальное время проведения 131,5 с

APDEX 0,228 означает, что подавляющее большинство операций проведения документа оцениваются пользователями как «неудовлетворительные». Пять пользователей в течение одного дня зафиксировали время проведения свыше 100 секунд.

Шаг 2. Анализ событий CALL в ТЖ

После фильтрации событий CALL по длительности (более 10 секунд) и сортировки по произведению средней длительности и количества вызовов выявились три лидера, связанные с одним и тем же контекстом — журналом документов закупок:

Контекст  Средняя длительность, с  Кол-во событий 
ЖурналДокументовЗакупки. ПриОповещенииОЗаписи ОформляемогоДокумента 89,04 74
ДинамическийСписок. ПолучитьДанные : ЖурналДокументовЗакупки. СписокДокументыЗакупки 79,51 48
ДинамическийСписок. ПолучитьДанные : ЖурналДокументов БезналичныеПлатежи. СписокПлатежей 108,31 10

Обращает на себя внимание характер событий: все они связаны с обновлением динамических списков. Событие ПриОповещенииОЗаписи ОформляемогоДокумента с 74 вызовами и средней длительностью 89 секунд — явный главный кандидат на исследование.

Шаг 3. Диагностика соотношения Duration/CpuTime

Конкретная запись в технологическом журнале для события ПриОповещении ОЗаписи ОформляемогоДокумента:

55:48.876004-25665004, CALL,1,process=rphost,...

Context=Форма.Вызов : Обработка. ЖурналДокументовЗакупки. Форма. СписокДокументов. Модуль.ПриОповещенииОЗаписи ОформляемогоДокумента,

...Memory=2869776, MemoryPeak=33339720, InBytes=2559, OutBytes=0, CpuTime=1828125

Ключевые числа (Duration выделено выше перед «CALL»):

• Duration = 25 665 004 мкс = 25,7 секунды — время которое прошло с начала серверного вызова до его полного завершения;

• CpuTime = 1 828 125 мкс = 1,8 секунды — чистое процессорное время, затраченное потоками операционной системы на выполнение кода внутри этого вызова без учета ожидания выполнения вызова СУБД.

Куда уходит время вызова.png

Разница: 25,7 − 1,8 = 23,9 секунды рабочий процесс кластера ожидал — с высокой вероятностью, данных от СУБД. Это 93% всего времени вызова. Вывод однозначен: узкое место не в коде «1С:Предприятия» (его выполнение занимает менее 2 секунд), а в SQL-запросах, которые этот код порождает.

Шаг 4. Анализ событий DBPOSTGRS

Среди событий DBPOSTGRS, связанных с контекстом обновления журнала закупок, обнаруживаются запросы к таблице _InfoRg105575. Регистр сведений с этим идентификатором используется механизмом формирования динамических списков. Ключевой запрос имеет следующие характеристики:30.353=AvgDurationSec, 30.353=TotalDurationSec, 1=Execs,

Sql=«SELECT … FROM _InfoRg105575 WHERE …»

Среднее время выполнения запроса — 30,4 секунды при единственном вызове. Это и есть источник задержки.

Шаг 5. Анализ тела запроса — LIKE с ведущим подстановочным символом

Изучение текста SQL-запроса раскрывает ключевую проблему. В блоке WHERE присутствует 12 условий следующего вида:

WHERE

  CAST(_Fld105600 AS NVARCHAR) LIKE '%Строка_поиска%'

  OR CAST(_Fld105601 AS NVARCHAR) LIKE '%Строка_поиска%'

  OR CAST(_Fld105602 AS NVARCHAR) LIKE '%Строка_поиска%'

  -- ... ещё 9 аналогичных условий ...

Платформа «1С:Предприятие» при активном поиске по строке в динамическом списке генерирует условие LIKE для каждой видимой колонки списка — чтобы обеспечить «поиск во всех полях». Маска LIKE '%строка%' с символом % в начале делает использование любого B-tree индекса невозможным по математическим причинам: индекс упорядочен по первому символу значения, но при ведущем % неизвестно, с какого символа начинается искомое вхождение. PostgreSQL вынужден выполнить полное последовательное сканирование таблицы _InfoRg105575 и проверить каждую строку против 12 условий.

Шаг 6. Связь с жалобами пользователей

Здесь важно понять механику: пользователи жалуются на медленное проведение документа, тогда как реальная причина — медленное обновление динамического списка, из которого открыт документ. Когда документ проводится и записывается, платформа генерирует серверное оповещение. Форма журнала закупок, открытая у пользователя, получает это оповещение и вызывает обработчик ПриОповещении ОЗаписи Оформляемого Документа, который обновляет динамический список. 

1С Предприятие тормозит.jpg

Пользователь видит: нажал «Провести и закрыть» → ждёт 100–130 секунд → операция завершена. Для него это «медленное проведение», хотя само по себе проведение могло занять 10 секунд.

Это классический пример, когда диагностика на основе только жалоб пользователей приводит исследователя по ложному следу.

Основные способы оптимизации запросов и кода

Выявленная проблема имеет конкретное решение, но в общем случае арсенал оптимизации охватывает три уровня воздействия.

Уровень запроса и прикладного кода

Устранение LIKE с ведущим % через отключение строкового поиска. Для описанного кейса наиболее простым и корректным решением является программное отключение поиска по строке в динамическом списке журнала документов закупок. Это можно реализовать через расширение конфигурации, установив свойство ПоискПоСтроке в НетПоискаПоСтроке для реквизита динамического списка. При отключении строкового поиска платформа автоматически переключается на расширенный поиск, который работает по текущему выделенному полю и использует условие вида LIKE 'строка%' (без ведущего %) — а это уже позволяет использовать индекс.

Индексирование временных таблиц в пакетных запросах. После помещения данных во временную таблицу конструкцией ПОМЕСТИТЬ необходимо явно создавать индексы по полям, используемым в последующих соединениях:

ИНДЕКСИРОВАТЬ ПО

  Ссылка,

  Номенклатура

Без этого каждое соединение с временной таблицей превращается в полное сканирование.

Параметризация виртуальных таблиц. Обращение к РегистрНакопления. Остатки() без параметров — это запрос остатков на все возможные даты. Всегда передавайте дату и, при возможности, список измерений:

РегистрНакопления. ТоварыНаСкладах. Остатки(

    &ДатаОстатков,Склад В (&СписокСкладов))

Платформа транслирует эти параметры в условия WHERE во вложенном подзапросе, радикально сокращая объём обрабатываемых данных.

Устранение неявных преобразований типов. При работе с составными типами необходимо явно указывать тип в условиях через ВЫРАЗИТЬ(Поле КАК Тип.Объект). Это формирует в SQL точечное условие по паре _TYPE/_ID вместо OR-цепочки по всем возможным типам.

Уровень архитектуры данных

Правильная настройка управляемых блокировок. При режиме управляемых блокировок разработчик явно указывает, какие данные блокируются при проведении документа. Избыточно широкие блокировки (например, блокировка всего регистра вместо конкретного измерения) создают конкуренцию между параллельно работающими пользователями. Рекомендуется проводить аудит блокировок через события ТЖ TLOCK и TTIMEOUT, сопоставляя их с транзакционными контурами в коде.

Архитектура оповещений и обновления форм. Серверные оповещения — удобный механизм, но при неправильном применении они превращаются в источник нагрузки. Если каждое проведение документа вызывает полное обновление тяжёлого динамического списка у всех пользователей, работающих с этим журналом, суммарная нагрузка растёт пропорционально числу пользователей. Архитектурное решение — ограничивать перечень событий, вызывающих обновление, и/или обновлять только изменившуюся строку, а не весь список.

Разделение аналитики и оперативных данных. Тяжёлые аналитические запросы, формирующие динамические списки с агрегациями по большим объёмам данных, целесообразно выносить в отдельные механизмы: фоновое задание для предрасчёта показателей, отдельная аналитическая витрина данных или использование СКД с предварительным отбором.

Уровень СУБД и инфраструктуры

Актуализация статистики. Оптимизатор PostgreSQL и SQL Server принимают решения о плане выполнения на основе статистики распределения данных в таблицах. При активной работе с базой данных статистика устаревает, и оптимизатор начинает строить неоптимальные планы: например, использует Nested Loop там, где нужен Hash Join, или наоборот. Регулярный запуск ANALYZE (PostgreSQL) или UPDATE STATISTICS (SQL Server) — обязательная часть регламентного обслуживания.

Очистка процедурного кэша (plan cache). SQL Server кэширует планы выполнения запросов. При изменении статистики данных или структуры таблиц закешированный план может стать неоптимальным. В критических ситуациях помогает DBCC FREEPROCCACHE (для очистки всего кэша или конкретного плана). Злоупотреблять не следует — кэш снижает нагрузку на компилятор планов.

Регламентное обслуживание индексов. Активная запись в таблицы фрагментирует B-tree индексы. Ежедневный регламент должен включать перестройку или реорганизацию фрагментированных индексов: REINDEX TABLE / ALTER INDEX … REBUILD. В PostgreSQL дополнительно важен VACUUM для возврата «мёртвых» страниц в пул свободного пространства и предотвращения раздувания таблиц.

Правильная конфигурация work_mem (PostgreSQL). При недостаточном значении work_mem PostgreSQL вынужден выполнять сортировку и хеш-соединения с использованием дисковых временных файлов вместо оперативной памяти. Для рабочих нагрузок «1С:Предприятия», интенсивно использующих агрегирующие запросы, увеличение work_mem до 64–256 МБ (с учётом максимального числа параллельных сессий) нередко даёт ощутимое снижение времени выполнения тяжёлых запросов.

Заключение: от ситуативного устранения к превентивному мониторингу

Описанный кейс — медленное проведение документа, за которым скрывалось серия 30-секундных полных сканирований таблиц из-за условия LIKE с ведущим % — наглядно демонстрирует несколько ключевых истин технологической экспертизы.

Во-первых, жалоба пользователя и реальная причина проблемы редко совпадают напрямую. Системный аналитик сказал бы «медленное проведение», администратор СУБД увидел бы «долгий SELECT на таблице регистра», а эксперт по «1С:Предприятие» нашёл бы связь: медленный поиск по строке в динамическом списке, обновляющемся по серверному оповещению в момент записи документа. Только совместный анализ данных подсистемы «Оценка производительности», технологического журнала и СУБД даёт полную картину.

Во-вторых, цена ситуационного расследования выше, чем превентивного мониторинга. К моменту, когда проблема была обнаружена, пользователи провели десятки тысяч операций с временем ожидания 30–130 секунд. Внедрение постоянного мониторинга через подсистему «Оценка производительности» БСП — с правильно расставленными замерами ключевых операций и целевыми значениями времени — позволяет обнаруживать деградацию на ранних стадиях, до того как она становится заметной пользователям.

В-третьих, технологический аудит должен быть регулярным. Изменение объёма данных, добавление новых пользователей, установка обновлений конфигурации — любой из этих факторов может изменить характер нагрузки и выявить узкие места, которых ранее не существовало или которые были скрыты меньшим объёмом данных.

Мониторинг APDEX.jpg

Рекомендуемая базовая практика для продуктивных систем на 1С:Предприятие:

• Постоянно: мониторинг APDEX ключевых операций через подсистему «Оценка производительности» БСП — с настроенными целевыми временами и регулярным просмотром замеров;

• Ежемесячно: анализ топа событий DBPOSTGRS/DBMSSQL по суммарному времени за период;

• Квартально: полный технологический аудит с анализом структуры индексов, статистики СУБД и профилей блокировок;

При каждом значимом обновлении конфигурации: повторный замер APDEX ключевых операций для раннего выявления регрессий производительности.

Только такой системный подход превращает производительность из источника постоянных инцидентов в управляемую характеристику информационной системы — с измеримыми метриками, понятными ответственными и предсказуемой динамикой изменений.

Владислав Терещенко
Автор статьи
Владислав Терещенко, Руководитель технического отдела
Нужна помощь специалиста?
Если у вас остались вопросы или требуется консультация — оставьте заявку, и наш специалист свяжется с вамив ближайшее время.