Все статьи

2 октября 2026 г.

Оптимизация запросов 1С через ИИ с передачей плана выполнения: MCP-сервер Графон

Почему план выполнения решает судьбу запроса

Запрос на языке 1С может выполняться за 200 мс или за 4 минуты при одинаково корректном синтаксисе. Разница живёт не в BSL, а в плане выполнения СУБД: Seq Scan против Index Seek, вложенные циклы против Hash Join, ошибка оценки кардинальности. Без плана любая оптимизация превращается в угадайку, потому что менеджер по производительности 1С показывает только итоговое время.

Классический процесс разбора запроса выглядит так:

  1. Инженер находит тяжёлый запрос в Центре управления производительностью (ЦУП).
  2. Выгружает план из технологического журнала (событие DBMSSQL с полем plan) или напрямую через EXPLAIN в MS SQL/PostgreSQL.
  3. Вручную сопоставляет узлы плана с текстом запроса и метаданными конфигурации.
  4. Правит запрос и повторяет цикл до победы.

Это часы ручной работы на один запрос. ИИ-агент способен сократить цикл до минут — но упирается в контекстное окно.

Слепая зона: почему ИИ не видит конфигурацию 1С целиком

Типовая ERP, УТ, ЗУП или КА — это:

  • гигабайты XML-метаданных;
  • сотни тысяч строк BSL в общих модулях, модулях объектов, менеджеров и форм;
  • десятки тысяч запросов, часть которых собирается динамически через СтрШаблон и СтрСоединить.

Если указать Claude Code или Cursor на всю выгрузку конфигурации в исходниках:

  • контекстное окно переполняется на первом же запросе по плану;
  • расход токенов растёт примерно в 10 раз — вы платите за XML, не относящийся к делу;
  • агент путает сигнатуры методов и выдумывает несуществующие реквизиты.

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

Графон: MCP-сервер с графом зависимостей конфигурации

Графон (https://grafonbase.ru) — локальный инструмент и MCP-сервер для 1С:Предприятие. Он индексирует конфигурацию и строит граф:

  • метаданные → реквизиты → типы;
  • общие модули → процедуры и функции → их вызовы;
  • подписки на события → обработчики;
  • запросы → таблицы и виртуальные таблицы.

ИИ-агент через протокол MCP обращается к Графону и получает точный срез вместо стога XML.

Инструменты, которые используются при разборе плана

| MCP-метод | Назначение | Что возвращает |
|---|---|---|
| graf_metadata_lookup | Поиск метаданных по имени | Реквизиты, типы, измерения, индексы |
| graf_function_signature | Сигнатура функции | Параметры, тип возврата, тело |
| graf_callers_of | Кто вызывает процедуру | Модули и строки вызовов |
| graf_query_by_table | Запросы к таблице | Тексты запросов и модули |
| graf_subscriptions | Подписки на событие | Обработчики и их модули |
| graf_query_plan_link | Связка плана с запросом | Срез «план → таблицы → реквизиты» |

Типичный промпт агенту выглядит так:

«Смотри план во вложении. Через graf_metadata_lookup подтяни состав измерений и индексы регистра ТоварыНаСкладах. Через graf_query_by_table верни все запросы к нему. Через graf_callers_of покажи, где они вызываются циклически.»

Агент делает 3–5 MCP-вызовов и получает ~18 000 токенов вместо ~180 000.

Сценарий 1: разбор тяжёлого запроса к регистру

ЦУП показывает запрос на 6 секунд:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Остатки.Номенклатура,
|    Остатки.Склад,
|    Остатки.КоличествоОстаток
|ИЗ
|    РегистрНакопления.ТоварыНаСкладах.Остатки(
|        &Дата,
|        Номенклатура В (&Номенклатура)) КАК Остатки
|ГДЕ
|    Остатки.Склад В (&Склады)";
Запрос.УстановитьПараметр("Дата", &Дата);
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Запрос.УстановитьПараметр("Склады", Склады);

План от СУБД:

Seq Scan on _AccumRg7042 (cost=0.00..482110.10 rows=1 width=42)
  Filter: (Fld7042 IN (...) AND _Fld7045 <= '2026-10-02')

Классический Seq Scan по таблице остатков. Передаём этот план и текст запроса агенту — он через graf_metadata_lookup видит, что Склад входит в состав измерений и покрыт индексом _AccumRg7042_ByDims. Условие в ГДЕ не даёт оптимизатору использовать индекс — фильтр ставится после материализации виртуальной таблицы.

Оптимизированный вариант:

Запрос.Текст =
"ВЫБРАТЬ
|    Остатки.Номенклатура,
|    Остатки.Склад,
|    Остатки.КоличествоОстаток
|ИЗ
|    РегистрНакопления.ТоварыНаСкладах.Остатки(
|        &Дата,
|        Склад В (&Склады)
|            И Номенклатура В (&Номенклатура)) КАК Остатки";

Условие переезжает в параметры виртуальной таблицы — план переключается с Seq Scan на Index Seek, время падает с 6 секунд до 120 мс.

Сценарий 2: циклический вызов, который не виден в плане

План на один вызов чистый, но суммарно модуль ест процессор. Классический антипаттерн:

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Остатки.КоличествоОстаток
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата,, Номенклатура = &Ном) КАК Остатки";
    Запрос.УстановитьПараметр("Дата", ТекущаяДата());
    Запрос.УстановитьПараметр("Ном", Выборка.Ссылка);
    Результат = Запрос.Выполнить();
КонецЦикла;

Через graf_callers_of агент видит: фрагмент вызывается в 14 местах, три из них — внутри циклов по 5–40 тыс. элементов. Переписываем на один запрос с массивом:

Запрос.Текст =
"ВЫБРАТЬ
|    Остатки.Номенклатура,
|    Остатки.КоличествоОстаток
|ИЗ
|    РегистрНакопления.ТоварыНаСкладах.Остатки(
|        &Дата,
|        Номенклатура В (&МассивНоменклатуры)) КАК Остатки";
Запрос.УстановитьПараметр("МассивНоменклатуры", МассивНоменклатуры);
Запрос.УстановитьПараметр("Дата", ТекущаяДата());

Одна поездка к СУБД вместо 40 000. Нагрузка падает на порядок.

Сравнение: с Графоном и без

| Метрика | Без Графона (вся конфигурация в контекст) | С Графоном (MCP-срез) |
|---|---|---|
| Токенов на задачу | ~180 000 | ~18 000 |
| Стоимость запроса (Sonnet) | ~$0.60 | ~$0.06 |
| Время до первой гипотезы | 8–12 минут | 40–60 секунд |
| Точность имён методов и реквизитов | 60–70 % (галлюцинации) | 99 %+ |
| Работа с регистром 40+ млн строк | контекст теряется | выдаёт точный срез индексов |
| Повторяемость результата | сильно варьируется | стабильна |

Чек-лист оптимизации запроса через ИИ

  1. Снимите план выполнения через ЦУП 1С или технологический журнал.
  2. Передайте агенту план и текст запроса.
  3. Дайте агенту доступ к MCP-инструментам Графона для получения метаданных и индексов регистра.
  4. Запросите через graf_callers_of все места вызова — исключите цикл.
  5. Убедитесь, что условия в виртуальных таблицах стоят в параметрах, а не в ГДЕ.
  6. Проверьте наличие подписок через graf_subscriptions — иногда «тяжёлый запрос» на самом деле триггерит обработчик.
  7. Примените правки и снова снимите план: сравнивайте Index Seek / Index Scan / Seq Scan.
  8. Зафиксируйте стоимость до/после в задаче.

Вывод

План выполнения без контекста метаданных бесполезен, а метаданные ERP или ЗУП не влезают в контекстное окно ИИ. Графон закрывает разрыв: строит граф зависимостей конфигурации и через MCP отдаёт агенту ровно тот срез, который нужен для конкретного запроса — измерения, индексы, вызовы, подписки. Результат: до 10 раз меньше токенов, ответы за минуты вместо часов и никаких выдуманных реквизитов в предложениях агента.