Кто и как выполняет запросы в 1С без обращения к таблицам базы данных?

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

В практике разработчика 1С часто возникает ситуация, когда необходимо обработать данные, которые еще не записаны в базу или были получены из внешних источников. Мы помещаем ТаблицуЗначений в Запрос, выполняем соединения, группировки и сортировки. На первый взгляд кажется, что раз обращения к реальным таблицам БД (справочникам или документам) нет, то и СУБД (SQL Server) в этом процессе не участвует. Но так ли это на самом деле?

Разберем детально механизм работы платформы «1С:Предприятие 8» в клиент-серверном варианте при обработке таблиц значений в языке запросов.

Где физически выполняется запрос к таблице значений?

Существует распространенное заблуждение, что если запрос не обращается к данным базы, то его выполняет непосредственно сервер приложений 1С своими внутренними алгоритмами. Однако это верно лишь отчасти и только для файлового варианта работы базы данных.

В клиент-серверном режиме платформа придерживается строгой архитектуры: любой объект типа Запрос транслируется в нативный SQL-код и отправляется на исполнение серверу баз данных (MS SQL, PostgreSQL, Oracle или IBM DB2). Рассмотрим, почему это происходит именно так:

  1. Унификация механизмов: Платформе проще использовать мощный движок СУБД для выполнения сложных операций (Join, Group By), чем реализовывать дублирующий функционал на сервере приложений.
  2. Масштабируемость: Обработка больших массивов данных требует значительных ресурсов памяти и процессора, которые на SQL-сервере обычно лучше оптимизированы.

Процесс трансляции запроса: анализ SQL-плана

Чтобы понять, что происходит «под капотом», проанализируем пример реального запроса 1С, который выбирает данные из переданного параметра &ВТ (Таблица Значений):


// Запрос в 1С
ВЫБРАТЬ
    ВТ.НомерСтроки КАК НомерСтроки,
    ВТ.Сумма КАК Сумма
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
    &ВТ КАК ВТ;

ВЫБРАТЬ
    ВременнаяТаблица.НомерСтроки,
    ВременнаяТаблица.Сумма
ИЗ
    ВременнаяТаблица;

Если мы воспользуемся консолью запросов или профайлером SQL, мы увидим, что 1С генерирует следующий T-SQL код:


-- 1. Инициализация структуры временной таблицы
INSERT INTO #tt271 WITH(TABLOCK) (_Q_001_F_000, _Q_001_F_001) 
SELECT TOP 0 CAST(NULL AS NUMERIC(10, 0)), CAST(NULL AS NUMERIC(15, 3))

-- 2. Наполнение таблицы данными из нашей ТЗ
INSERT INTO #tt271 (_Q_001_F_000, _Q_001_F_001) 
VALUES(1, 123.00), (2, 11.00), (3, -344.02)

-- 3. Итоговая выборка
SELECT T1._Q_001_F_000, T1._Q_001_F_001 
FROM #tt271 T1 WITH(NOLOCK)

Здесь #tt271 — это временная таблица на стороне SQL-сервера. Разберем по шагам, что сделал сервер 1С:

Роль системной базы tempdb

Важно понимать, что даже если вы не трогаете основные таблицы вашей ИБ, нагрузка на дисковую подсистему всё равно создается. Все временные таблицы (начинающиеся с символа #) создаются в системной базе данных tempdb.

Если ваша ТаблицаЗначений содержит сотни тысяч строк, 1С будет вынуждена сериализовать эти данные, передать их по сети на SQL-сервер, а тот, в свою очередь, запишет их в tempdb. В некоторых случаях это может стать узким местом, особенно если tempdb расположена на медленных дисках или ограничена в росте.

Когда использование запроса к ТЗ оправдано?

Многие разработчики спорят: стоит ли использовать запрос или лучше обойтись методами объекта ТаблицаЗначений (НайтиСтроки(), Скопировать(), Свернуть()). Выясним преимущества запросов:

  1. Сложные условия: В методе НайтиСтроки() нельзя использовать сложные логические операторы ИЛИ, НЕ или вложенные условия. В запросе же доступна вся мощь условий ГДЕ.
  2. Левое соединение (LEFT JOIN): Это самый эффективный способ сопоставить две таблицы данных. Реализовать это циклом в коде 1С будет значительно медленнее на больших объемах.
  3. Индексация: Это критически важный момент. В запросе мы можем написать ИНДЕКСИРОВАТЬ ПО.... В этом случае SQL-сервер создаст индекс для временной таблицы, что на порядки ускорит последующие соединения.

Влияние типизации на производительность

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

Например, для колонки с типом «ЛюбаяСсылка» SQL-сервер создаст несколько полей (идентификатор типа, бинарный код ссылки), что увеличит размер временной таблицы в разы. Поэтому всегда типизируйте колонки ТЗ перед передачей их в запрос — это сэкономит память и ускорит передачу данных по сети.

Особенности файлового режима

Рассмотрим кратко файловый вариант. В нем «движком» базы данных выступает сама библиотека платформы. Здесь трансляции в T-SQL не происходит, но логика остается похожей: создаются внутренние структуры в оперативной памяти (или во временных файлах на диске), которые обрабатываются тем же кодом, что и обычные таблицы .1CD. Накладные расходы на сеть здесь отсутствуют, но общая производительность ограничена мощностью одного рабочего процесса.

Итоги

Запросы к таблицам значений — это мощный инструмент, но его нужно использовать осознанно. Мы выяснили, что основной объем вычислительной работы в клиент-серверном варианте выполняет SQL-сервер.

Основные правила для оптимизации:

← На главную