При разработке конфигураций и доработке типовых решений на платформе 1С:Предприятие разработчики часто сталкиваются с выбором: сформировать один большой пакетный запрос или выполнить последовательность отдельных вызовов через объект Запрос, используя при необходимости МенеджерВременныхТаблиц. Разберем подробно, какие практические, архитектурные и производительные преимущества дает применение пакетных запросов.
Рассмотрим, как происходит физическое взаимодействие между кластером серверов 1С (процессом rphost) и сервером СУБД (MS SQL Server, PostgreSQL и др.):
Запрос.Выполнить() платформа формирует отдельный сетевой пакет, отправляет его по сети в СУБД, ожидает компиляции/выполнения плана и возврата дескриптора результата. Если в коде выполняется цепочка из 5–10 запросов, накладные расходы на сетевой пинг и контекстное переключение суммируются.ВыполнитьПакет() или Выполнить() платформа транслирует весь текст пакета и отправляет его серверу СУБД единым блоком команд за одно сетевое обращение. СУБД последовательно исполняет все инструкции пакета внутри единого контекста соединения.С точки зрения поддержки кода пакетный запрос предоставляет значительные удобства:
Выясним, где физически хранятся временные таблицы и как ими управлять. Временные таблицы всегда создаются и хранятся на стороне СУБД (например, в базе tempdb для MS SQL Server), независимо от того, используется ли МенеджерВременныхТаблиц или пакетный запрос.
Преимущество пакета заключается в автоматическом управлении жизненным циклом таких таблиц:
МенеджерВременныхТаблиц, область видимости и время жизни временных таблиц ограничены выполнением данного пакета. После завершения запроса ресурсы на стороне СУБД освобождаются автоматически.МенеджерВременныхТаблиц в явном виде временные таблицы продолжают занимать память и дисковое пространство СУБД до тех пор, пока менеджер не будет уничтожен или закрыт сборщиком мусора, либо пока не будет выполнен явный запрос на их удаление (УНИЧТОЖИТЬ ВТ_ИмяТаблицы).ИНДЕКСИРОВАТЬ ПО, что существенно ускоряет последующие соединения.Посмотрим на пример оформления пакетного запроса с подготовкой данных и получением нескольких результатов:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.ВНаличииОстаток КАК Остаток
|ПОМЕСТИТЬ ВТ_Остатки
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_Остатки.Номенклатура КАК Номенклатура,
| ВТ_Остатки.Остаток КАК Остаток,
| ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
|ИЗ
| ВТ_Остатки КАК ВТ_Остатки
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК ЦеныНоменклатурыСрезПоследних
| ПО ВТ_Остатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ЗаказыКлиентов.Ссылка КАК Заказ,
| ЗаказыКлиентов.СуммаДокумента КАК Сумма
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказыКлиентов
|ГДЕ
| ЗаказыКлиентов.Проведен";
Запрос.УстановитьПараметр("Период", ТекущаяДатаСеанса());
// Получаем массив результатов для каждого запроса пакета
МассивРезультатов = Запрос.ВыполнитьПакет();
ТаблицаОстатковИЦен = МассивРезультатов[1].Выгрузить();
ТаблицаЗаказов = МассивРезультатов[2].Выгрузить();
Платформа 1С предоставляет три способа выполнения пакетных запросов в зависимости от требуемой задачи:
Запрос.Выполнить() — исполняет весь пакет на сервере СУБД, но возвращает объект РезультатЗапроса только для самого последнего запроса в пакете. Это наиболее экономный по оперативной памяти вариант, если промежуточные выборки в коде 1С не требуются.Запрос.ВыполнитьПакет() — возвращает массив результатов (Массив). Позиция каждого элемента строго соответствует номеру запроса в пакете. При этом запросы, создающие временные таблицы, возвращают пустой результат, а инструкции УНИЧТОЖИТЬ возвращают Неопределено.Запрос.ВыполнитьПакетСПромежуточнымиДанными() — возвращает реальные выборки даже для промежуточных временных таблиц, что крайне полезно при профилировании и отладке сложных расчетов.Проанализируем ситуации, когда единый пакет использовать нецелесообразно:
МенеджерВременныхТаблиц.