Гайд 1С: Использование пакетных запросов для минимизации сетевого трафика с СУБД
При выполнении тяжелых расчетных алгоритмов и отчетов наблюдается следующее:
- Высокие задержки времени выполнения из-за большого количества сетевых обращений между
rphostи СУБД (Network Round-Trip Latency). - Ожидания по событию
ASYNC_NETWORK_IOв MS SQL Server. - Перегрузка оперативной памяти из-за многократной передачи промежуточных выборок на сервер 1С и обратно в СУБД.
- Фрагментация базы данных
tempdbпри некорректном создании неиндексированных временных таблиц.
1. Объединение одиночных запросов в единый пакет
Вместо выполнения серии последовательных запросов в цикле объединяйте их через точку с запятой (;) в один пакетный запрос. СУБД скомпилирует общий план и выполнит его за один сетевой раунд-трип:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Т.Номенклатура КАК Номенклатура,
| СУММА(Т.Количество) КАК Количество
|ПОМЕСТИТЬ ВТ_Товары
|ИЗ
| &ТаблицаТоваров КАК Т
|СГРУППИРОВАТЬ ПО
| Т.Номенклатура
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура
|;
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ.Номенклатура КАК Номенклатура,
| ВТ.Количество КАК Количество,
| ЕСТЬNULL(Остатки.ВНаличииОстаток, 0) КАК Остаток
|ИЗ
| ВТ_Товары КАК ВТ
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура В (
| ВЫБРАТЬ ВТ_Товары.Номенклатура ИЗ ВТ_Товары)) КАК Остатки
| ПО ВТ.Номенклатура = Остатки.Номенклатура";
Запрос.УстановитьПараметр("ТаблицаТоваров", ДанныеТаблицы);
РезультатыПакетного = Запрос.ВыполнитьПакет();2. Обязательное индексирование временных таблиц (ВТ)
Всегда добавляйте секцию ИНДЕКСИРОВАТЬ ПО для полей временных таблиц, которые в последующих запросах пакета участвуют в условиях ПО (JOIN) или ГДЕ (WHERE). Это позволяет оптимизатору СУБД использовать эффективные соединения Index Seek / Merge Join вместо медленного Hash Match / Nested Loops со сканированием всей ВТ.
Частые вопросы (FAQ)
Чем ВыполнитьПакет() отличается от ВыполнитьПакетЗапросов()?
ВыполнитьПакет() возвращает массив всех результатов запросов пакета. ВыполнитьПакетЗапросов() возвращает объект 'ПакетОтображенияРезультатов' и позволяет обходить результаты последовательно, экономя память сервера 1С.
Где физически хранятся временные таблицы (ПОМЕСТИТЬ ВТ)?
Временные таблицы создаются непосредственно в служебной базе данных tempdb (в MS SQL Server) или во временном табличном пространстве (в PostgreSQL).
Нужно ли явно уничтожать временные таблицы в конце пакета запросов?
Если временная таблица содержит десятки тысяч строк и в рамках того же сеанса выполняются другие запросы с МенеджеромВременныхТаблиц, ее необходимо явно удалить конструкцией 'УНИЧТОЖИТЬ ВТ_Имя', чтобы освободить страницы tempdb.
Каково максимальное количество таблиц параметров (&Таблица), которое можно передать в запрос?
Платформа не ограничивает строго количество таблиц, но передача более 5-10 тяжелых таблиц в параметрах создает колоссальный сетевой оверхед на сериализацию данных между 1С и СУБД.