Когда запрос в 1С начинает выполняться неоправданно долго, первым делом стоит проанализировать его структуру. Часто причиной тормозов становится не объем данных, а некорректное использование методов обращения к объектам базы данных и неправильное построение условий. В этой статье мы разберем основные принципы оптимизации на примере решения конкретной задачи.
Одной из самых частых ошибок является обращение к реквизитам через «точку» в условии ГДЕ, например: Сотрудник.Родитель.Код = \"Вз\". Такой подход заставляет систему выполнять дополнительные соединения и существенно замедляет выборку, так как СУБД вынуждена постоянно обращаться к родительским объектам для проверки каждого элемента.
Правильный подход: заранее получите ссылку на нужную группу (родителя) в коде 1С и передайте её в запрос как параметр. Это позволит оптимизатору СУБД работать с готовым значением, а не вычислять его на лету для каждой строки.
Рассмотрим, как это выглядит в коде:
// Плохо:
ГДЕ Сотрудник.Родитель.Код = "Вз"
// Хорошо:
// 1. Получаем ссылку в коде:
ГруппаСотрудников = Справочники.Сотрудники.НайтиПоКоду("Вз");
// 2. Передаем в параметры запроса:
Запрос.УстановитьПараметр("Родитель", ГруппаСотрудников);
// 3. Используем в запросе:
ГДЕ Сотрудник.Родитель = &Родитель
Многие разработчики пишут условия фильтрации в блоке ГДЕ, уже после получения данных из таблицы. Это критическая ошибка, если речь идет о виртуальных таблицах, таких как СрезПоследних или Остатки. Система сначала выбирает все записи из регистра, а только потом отфильтровывает ненужное.
Рекомендация: максимально переносите все возможные условия непосредственно в параметры виртуальной таблицы. Это позволит СУБД ограничить выборку еще на этапе обращения к физической таблице регистра.
Пример оптимизации:
// Плохо:
ВЫБРАТЬ * ИЗ РегистрСведений.СотрудникПоДоговору.СрезПоследних КАК Т
ГДЕ Т.Сотрудник = &Сотрудник
// Хорошо:
ВЫБРАТЬ * ИЗ РегистрСведений.СотрудникПоДоговору.СрезПоследних(, Сотрудник = &Сотрудник) КАК Т
В представленном вами запросе наблюдается избыточность: одни и те же условия проверяются несколько раз в разных временных таблицах. Каждый раз, когда вы делаете запрос к временной таблице или повторяете условие, вы заставляете систему выполнять лишнюю работу.
ВЫРАЗИТЬ. Постоянное приведение типов в условиях соединения заставляет СУБД выполнять сложные операции преобразования, что негативно сказывается на использовании индексов.ИНДЕКСИРОВАТЬ ПО является ключевой для производительности больших выборок.ИЛИ в запросах к регистрам часто ломает индексы. Если возможно, разбейте запрос на части или используйте временные таблицы с заранее отобранными данными.Чтобы понять, где именно «буксует» ваш запрос, выполните следующие шаги:
Table Scan (полное сканирование таблицы) — это главный враг быстрого запроса.Применение этих методов позволит вам не только ускорить работу текущего отчета, но и в целом повысить качество разрабатываемого кода, избавляясь от «тяжелых» конструкций, которые создают неоправданную нагрузку на сервер баз данных.