Почему отчет, содержащий запросы в цикле, работает в 20 раз быстрее на серверной базе?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Различие архитектур: Файловый вариант против Серверного

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

В серверном варианте (клиент-сервер) работа кардинально меняется:

  1. Вынос логики на сервер 1С: Основная часть кода выполняется на сервере приложений 1С, что значительно уменьшает задержки при обмене данными между клиентом и сервером.
  2. Роль СУБД (MS SQL, PostgreSQL): Тяжелые вычисления передаются на уровень SQL-сервера. Профессиональные СУБД обладают мощными планировщиками запросов и развитыми алгоритмами кэширования.
  3. Кэширование планов выполнения: Когда один и тот же запрос (даже если он вызывается в цикле для разных параметров) приходит на SQL-сервер, оптимизатор может распознать структуру запроса и использовать уже скомпилированный план выполнения, что колоссально ускоряет повторные обращения.

Разберем механизмы оптимизации SQL

Важно понимать, что при выполнении запросов в цикле на серверной базе, SQL-сервер может осуществлять следующее:

Однако, как отметили специалисты, полагаться на «интеллект» СУБД при написании кода — это рискованная стратегия. Если в одном случае MS SQL удачно закешировал план, то в другом — при изменении статистики или состава данных — план может измениться, и отчет снова станет работать крайне медленно.

Почему «запросы в цикле» — это антипаттерн?

Рассмотрим подробнее, почему профессиональные разработчики 1С стараются избегать запросов в цикле:

Непредсказуемость: Оптимизатор СУБД может «устать» или ошибиться при выборе плана выполнения для сотен однотипных запросов. В итоге время выполнения может внезапно вырасти в разы при изменении данных в базе.

Накладные расходы: Каждое обращение к серверу через цикл — это сетевой обмен и транзакционные затраты. Даже если сервер 1С находится рядом с СУБД, 1000 итераций всегда медленнее, чем один пакетный запрос, который обрабатывает весь массив номенклатуры сразу.

Как правильно перестроить архитектуру отчета

Чтобы отчет стал надежным и предсказуемым, проанализируем следующие рекомендации:

  1. Использование пакетных запросов: Вместо цикла для каждой номенклатуры, попробуйте передать весь массив номенклатуры в один запрос через параметр.
  2. Применение временных таблиц: Используйте конструкцию ПОМЕСТИТЬ, чтобы сохранить промежуточные результаты в ВременныеТаблицы. Это позволяет разбить сложный алгоритм на последовательные этапы обработки данных внутри одной транзакции на стороне SQL-сервера.

Посмотрим на пример логики перевода цикла в пакетный запрос:


// Вместо цикла по номенклатуре:
Для Каждого Элемент Из МассивНоменклатуры Цикл
    Запрос = Новый Запрос;
    Запрос.Текст = "... сложный текст запроса ...";
    // ... выполнение ...
КонецЦикла;

// Используем пакетный запрос:
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ Номенклатура
|ПОМЕСТИТЬ ВТ_Номенклатура
|ИЗ &МассивНоменклатуры КАК Номенклатура;
|
|ВЫБРАТЬ ...
|ИЗ ВТ_Номенклатура КАК ВТ
|ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документы КАК Док ...";
Запрос.УстановитьПараметр("МассивНоменклатуры", МассивНоменклатуры);
Результат = Запрос.Выполнить();

Заключение и выводы

Ускорение отчета в 20 раз при переходе на серверную базу — это победа не кода, а архитектуры SQL. Тем не менее, не стоит забывать, что «скрытая» оптимизация на стороне сервера — это не гарантия стабильности. Для того чтобы отчет работал быстро всегда, независимо от объема накопленных данных, лучше потратить время на переработку цикла в сторону пакетных запросов. Это позволит вам точно контролировать план выполнения, использовать индексы и временные таблицы, а также значительно облегчит последующую отладку через консоль запросов.

← На главную