Как оптимизировать сложный запрос в 1С, который работает слишком медленно?

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

Когда запрос в 1С начинает выполняться неоправданно долго, первым делом стоит проанализировать его структуру. Часто причиной тормозов становится не объем данных, а некорректное использование методов обращения к объектам базы данных и неправильное построение условий. В этой статье мы разберем основные принципы оптимизации на примере решения конкретной задачи.

Оптимизация условий обращения через точку

Одной из самых частых ошибок является обращение к реквизитам через «точку» в условии ГДЕ, например: Сотрудник.Родитель.Код = \"Вз\". Такой подход заставляет систему выполнять дополнительные соединения и существенно замедляет выборку, так как СУБД вынуждена постоянно обращаться к родительским объектам для проверки каждого элемента.

Правильный подход: заранее получите ссылку на нужную группу (родителя) в коде 1С и передайте её в запрос как параметр. Это позволит оптимизатору СУБД работать с готовым значением, а не вычислять его на лету для каждой строки.

Рассмотрим, как это выглядит в коде:


// Плохо:
ГДЕ Сотрудник.Родитель.Код = "Вз"

// Хорошо:
// 1. Получаем ссылку в коде:
ГруппаСотрудников = Справочники.Сотрудники.НайтиПоКоду("Вз");

// 2. Передаем в параметры запроса:
Запрос.УстановитьПараметр("Родитель", ГруппаСотрудников);

// 3. Используем в запросе:
ГДЕ Сотрудник.Родитель = &Родитель

Перенос условий в параметры виртуальных таблиц

Многие разработчики пишут условия фильтрации в блоке ГДЕ, уже после получения данных из таблицы. Это критическая ошибка, если речь идет о виртуальных таблицах, таких как СрезПоследних или Остатки. Система сначала выбирает все записи из регистра, а только потом отфильтровывает ненужное.

Рекомендация: максимально переносите все возможные условия непосредственно в параметры виртуальной таблицы. Это позволит СУБД ограничить выборку еще на этапе обращения к физической таблице регистра.

Пример оптимизации:


// Плохо:
ВЫБРАТЬ * ИЗ РегистрСведений.СотрудникПоДоговору.СрезПоследних КАК Т
ГДЕ Т.Сотрудник = &Сотрудник

// Хорошо:
ВЫБРАТЬ * ИЗ РегистрСведений.СотрудникПоДоговору.СрезПоследних(, Сотрудник = &Сотрудник) КАК Т

Борьба с дублированием данных и лишними соединениями

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

  1. Минимизируйте использование ВЫРАЗИТЬ. Постоянное приведение типов в условиях соединения заставляет СУБД выполнять сложные операции преобразования, что негативно сказывается на использовании индексов.
  2. Проверяйте план выполнения. Если вы используете временные таблицы, убедитесь, что вы индексируете поля, по которым планируете делать соединения. Инструкция ИНДЕКСИРОВАТЬ ПО является ключевой для производительности больших выборок.
  3. Избавляйтесь от логических «ИЛИ» в условиях. Использование ИЛИ в запросах к регистрам часто ломает индексы. Если возможно, разбейте запрос на части или используйте временные таблицы с заранее отобранными данными.

Алгоритм проверки производительности

Чтобы понять, где именно «буксует» ваш запрос, выполните следующие шаги:

  1. Замер производительности. Воспользуйтесь инструментом «Замер производительности» в Конфигураторе, чтобы увидеть, какой именно фрагмент кода потребляет больше всего процессорного времени.
  2. Анализ плана запроса. Используйте технологический журнал или консоль запросов с поддержкой замера плана выполнения. Ищите операции Table Scan (полное сканирование таблицы) — это главный враг быстрого запроса.
  3. Упрощение. Если запрос слишком сложен, попробуйте разбить его на несколько этапов, помещая промежуточные результаты в массив или таблицу значений в коде 1С, и передавая их дальше параметрами.

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

← На главную