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

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

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

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

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

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

Ошибки в понимании контекста выполнения приводят к типовым проблемам: сообщению «Процедура или функция с указанным именем не определена», передаче несериализуемых данных между клиентом и сервером и резкому падению производительности из-за множества серверных вызовов. Разберём каждый уровень выполнения и практические правила выбора контекста.

Три уровня выполнения: клиент, сервер 1С, СУБД

Архитектура 1С:Предприятия в клиент-серверном варианте трёхзвенная. Первое звено — клиентское приложение (тонкий, толстый или веб-клиент), которое отвечает за интерфейс и клиентскую логику. Второе звено — кластер серверов 1С, где исполняется серверный код: бизнес-логика, обращения к объектам данных, построение и выполнение запросов. Третье звено — система управления базами данных (MS SQL Server, PostgreSQL, Oracle, IBM DB2), где физически хранятся таблицы.

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

Важно различать «выполнение запроса» и «выполнение кода с запросом». Код (циклы, условия, обход выборки) выполняется в том контексте, где скомпилирована процедура. Физическая выборка из таблиц — всегда на стороне хранения данных. В файловом варианте эти два уровня совмещены в одном процессе.

Директивы компиляции и контекст выполнения

Директивы компиляции указывают платформе, где будет скомпилирована и исполнена процедура или функция формы. Основные директивы: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста. Если директива не указана в модуле формы, код по умолчанию компилируется в контексте «клиент-сервер» — доступен в обоих контекстах, но с ограниченным набором объектов.

Процедуры &НаКлиенте не могут напрямую выполнять запросы к базе данных в тонком и веб-клиенте: объект Запрос там недоступен или его выполнение невозможно из-за отсутствия прямого доступа к данным. Поэтому стандартный шаблон — клиентская процедура вызывает серверную, та выполняет запрос и возвращает результат (например, массив структур или таблицу значений, сериализуемую для передачи).

Директива &НаСервереБезКонтекста предпочтительнее для процедур, которым не нужны данные формы: вызов дешевле, потому что на сервер не передаётся весь контекст формы с реквизитами. Это заметно ускоряет работу при частых серверных вызовах из форм с большим числом реквизитов.

Порядок организации запроса из клиентского кода
  1. 1
    Создайте в модуле формы серверную функцию с директивой &НаСервереБезКонтекста
  2. 2
    Внутри сформируйте объект Запрос, установите текст и параметры
  3. 3
    Выполните запрос и преобразуйте результат в сериализуемый тип: массив структур или таблицу значений
  4. 4
    Верните результат клиентской процедуре и обработайте его в интерфейсе
  5. 5
    Проверьте, что за один обработчик не выполняется множество отдельных серверных вызовов

Выполнение запросов в разных типах клиентов

Толстый клиент — единственный режим, в котором код &НаКлиенте может работать с объектами базы данных напрямую, включая выполнение запросов с клиента. Это наследие двухзвенной архитектуры. Однако такой подход в клиент-серверном варианте вреден: каждый запрос идёт с рабочей станции в СУБД по сети, а обработка больших выборок нагружает клиентскую машину.

Тонкий клиент и веб-клиент не имеют прямого доступа к СУБД. Весь код работы с данными — запросы, объектные операции, транзакции — исполняется только на сервере 1С. Поэтому при разработке под управляемое приложение запросы всегда размещают в серверных процедурах или в общих модулях с признаком «Сервер».

Внешнее соединение (COM, через V83.COMConnector) работает как отдельный клиентский процесс: код в нём исполняется на стороне вызывающего приложения, но обращения к базе проходят через сервер 1С в клиент-серверном варианте. Фоновые задания и регламентные задания всегда выполняются на сервере, и запросы внутри них — тоже серверные.

Режим работыГде исполняется код с запросомГде физически выполняется выборка
Файловый вариант, любой клиентВ процессе клиентского приложенияТам же, чтение файла базы
Толстый клиент, клиент-серверНа клиенте или сервере (по директивам)На сервере СУБД
Тонкий/веб-клиент, клиент-серверТолько на сервере 1СНа сервере СУБД
Фоновое и регламентное заданиеНа сервере 1СНа сервере СУБД

Общие модули и признаки запуска

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

Частая архитектурная ошибка — включать у одного модуля и клиентский, и серверный признаки, а затем размещать в нём запросы. В тонком клиенте такой модуль будет компилироваться и на клиенте, где обращение к базе недоступно, что приводит к ошибкам исполнения. Правильный подход — разделять модули: клиентские для интерфейсной логики, серверные для работы с данными.

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

Запросы в файловом варианте: особенности

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

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

Ограничивайте выборки отборами и периодами даже в файловом варианте. Запрос, выбирающий весь регистр накопления за все годы, в файловом режиме может надолго заблокировать работу пользователя, потому что вся обработка идёт в его сеансе.

Производительность: как место выполнения влияет на скорость

Главное правило оптимизации — минимизировать количество серверных вызовов и объём передаваемых между клиентом и сервером данных. Каждый вызов серверной процедуры из клиентского кода — это сетевой обмен с сериализацией параметров. Десять вызовов с мелкими запросами почти всегда медленнее одного вызова с пакетным запросом.

Второй аспект — объём результата. Если серверная функция возвращает таблицу значений на десятки тысяч строк, она целиком сериализуется и передаётся клиенту. Лучше выполнять обработку данных на сервере и возвращать только агрегированный или ограниченный результат, нужный для отображения.

Третий аспект — запросы в цикле. Конструкция, где на каждой итерации цикла выполняется отдельный запрос, — классическая причина медленной работы. Заменяйте её одним запросом с условием «В» по списку значений или временной таблицей. Проверить наличие таких проблем помогает замер производительности в конфигураторе и технологический журнал кластера.

Типичные ошибки
01
Выполнение запроса в клиентской процедуре тонкого клиента — ошибка компиляции или исполнения, так как доступа к данным нет
02
Запрос внутри цикла обхода выборки — многократные обращения к СУБД и резкое падение скорости
03
Возврат на клиент огромных таблиц значений — долгая сериализация и передача по сети
04
Использование &НаСервере вместо &НаСервереБезКонтекста без необходимости — на сервер передаётся весь контекст формы
05
Разработка только в файловом режиме без проверки в клиент-серверном — код ломается после перехода на сервер

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

Определить фактическое место выполнения помогает несколько инструментов. Информационная строка и настройки публикации показывают режим базы: файловый или клиент-серверный. В коде функции ТипЗапускаКлиента и режимы системной информации позволяют программно определить контекст.

Замер производительности в конфигураторе (Отладка → Замер производительности) показывает, какие строки кода занимают время и сколько раз вызывались серверные процедуры. Технологический журнал кластера фиксирует события DBMSSQL/DBPOSTGRS — фактические запросы к СУБД, что подтверждает выполнение выборки на стороне базы данных.

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

Контрольные точки

Как проверить результат

Контекст процедуры с запросом
Норма

Директива &НаСервере или &НаСервереБезКонтекста, либо серверный общий модуль

Тревожный признак

Запрос в &НаКлиенте в тонком/веб-клиенте

Количество серверных вызовов из формы
Норма

Один вызов на действие пользователя, пакетная передача данных

Тревожный признак

Серверные вызовы внутри цикла обхода строк

Объём возвращаемых данных
Норма

Только нужные поля и строки с отбором

Тревожный признак

Вся таблица без отбора передаётся на клиента

Время выполнения запроса
Норма

Стабильное время на копии базы, адекватный план в СУБД

Тревожный признак

Резкие скачки времени, полные сканирования таблиц

Часто задаваемые вопросы

Можно ли выполнить запрос на клиенте в тонком клиенте?

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

Чем &НаСервере отличается от &НаСервереБезКонтекста?

Процедура &НаСервере получает доступ к данным формы, но при вызове весь контекст формы сериализуется и передаётся на сервер. &НаСервереБезКонтекста работает без данных формы, вызов дешевле и быстрее. Если данные формы не нужны, всегда выбирайте вариант без контекста.

Где выполняются запросы в фоновых заданиях?

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

Почему запрос работает в файловой базе, но падает после перехода на клиент-сервер?

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

Как узнать, какой SQL сформировала платформа из запроса 1С?

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

Влияет ли привилегированный режим на место выполнения запроса?

Нет. Привилегированный режим отключает проверку прав доступа к объектам, но не меняет контекст исполнения: код выполняется там, где скомпилирован — на клиенте или на сервере.

Итог

Что важно запомнить

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