К статье
Практический материал

Разработка и Конфигурация · 5 мин

Где выполняется запрос в 1С: клиент, сервер и СУБД

Разбираем, где выполняется запрос в 1С: на клиенте, сервере 1С или в СУБД. Директивы компиляции, передача данных и типичные ошибки производительности.

Вопрос «где выполняется запрос в 1С» возникает у разработчиков в двух ситуациях: когда нужно понять, почему код работает медленно, и когда компилятор выдаёт ошибку о недоступности контекста. Короткий ответ: сам запрос к данным всегда выполняется в системе управления базами данных (СУБД) — в клиент-серверном варианте это MS SQL Server, PostgreSQL, Oracle или IBM DB2, в файловом — встроенный движок файловой базы. Но код, который формирует и вызывает запрос, исполняется на сервере 1С:Предприятия или на клиенте, и от этого зависит производительность и доступность объектов.

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

Понимание этой схемы критично для оптимизации. Если разработчик вызывает запрос в цикле на клиенте, каждая итерация порождает сетевой вызов клиент → сервер → СУБД и обратно. Тот же запрос, выполненный один раз на сервере с передачей таблицы значений как параметра, отработает на порядки быстрее. Ниже разберём, как платформа распределяет выполнение кода и как управлять местом исполнения запросов.

Трёхуровневая архитектура: кто за что отвечает

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

Когда разработчик пишет на встроенном языке Запрос.Выполнить(), происходит следующее: платформа транслирует текст запроса на языке 1С в SQL-диалект конкретной СУБД, отправляет его на сервер баз данных, получает результат и материализует его в объекте «РезультатЗапроса». Физическое сканирование таблиц, соединения, сортировка и группировка происходят именно в СУБД — платформа 1С сама данные не перебирает.

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

Директивы компиляции: как указать, где исполняется код

Место исполнения процедуры или функции в модуле формы определяется директивой компиляции. Доступны четыре основных варианта: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста и &НаКлиентеНаСервереБезКонтекста. В общих модулях место исполнения задаётся флагами «Сервер», «Клиент (управляемое приложение)» и другими свойствами модуля.

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

Типовой приём для формы: клиентская процедура обрабатывает нажатие кнопки, вызывает серверную процедуру, та выполняет запрос и возвращает результат в виде массива структур или заполняет реквизит формы. Передавать между клиентом и сервером можно только сериализуемые данные — сам объект «Запрос» или «ВыборкаИзРезультатаЗапроса» на клиент передать нельзя.

bsl
&НаКлиенте
Процедура ЗагрузитьДанные(Команда)
	ЗагрузитьДанныеНаСервере();
КонецПроцедуры

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

В каком звене физически выполняется SQL

Платформа не выполняет запросы сама — она выступает транслятором и посредником. Текст на языке запросов 1С преобразуется в SQL с учётом особенностей конкретной СУБД: для PostgreSQL и MS SQL один и тот же запрос 1С породит разный SQL-код. Индексы, планы выполнения, статистика — всё это живёт в СУБД, и настройка производительности базы делается средствами самой СУБД.

Увидеть реальный SQL-текст можно через технологический журнал с событием DBMSSQL (для MS SQL), DBPOSTGRS, DBORACLE или DB2. Это основной инструмент диагностики медленных запросов: сначала в техножурнале находится SQL-текст и длительность, затем план запроса анализируется средствами СУБД.

Консоль запросов и отладчик показывают логику на уровне языка 1С, но не показывают, что реально происходит в базе. Два синтаксически похожих запроса могут породить SQL с радикально разной стоимостью — например, соединение с виртуальной таблицей без отборов разворачивается в тяжёлый подзапрос по всей таблице итогов.

Клиент или сервер: где правильно вызывать запрос

Правило простое: любой запрос к базе должен выполняться на сервере. На клиенте в управляемом приложении объект «Запрос» недоступен, а в толстом клиенте его использование приводит к тому, что весь трафик с СУБД идёт через компьютер пользователя, что в разы медленнее и нагружает сеть.

Главная ошибка производительности — запросы в цикле. Если для каждой строки таблицы вызывается отдельный запрос, каждая итерация — это обращение к СУБД с сетевыми накладными расходами. Правильный приём: собрать данные в таблицу значений, передать её в запрос через временную таблицу и выполнить одно обращение с соединением.

Ещё один аспект — контекст сервера. Процедуры &НаСервере в форме при каж