Друзья, в обработке реализовано:
- Добавление и выполнение запросов в обычном / привилегированном режиме
В Заметках из Зазеркалья есть публикация, что платформа 8.5 начнет поддерживать пакетную обработку запросов. Теперь когда мы описываем пакетный запрос, есть шансы что это будет выполнено за 1 обращение к СУБД, а не как сейчас, 1 обращение на каждый пакет.
Но пока наши продуктивные базы не перешли на новую версию платформы, можно применить альтернативный подход - взять все пакеты с выборкой и соединить в 1 запрос через "ОБЪЕДИНИТЬ ВСЕ".
Чтобы реализовать данный подход в этом решении используется комбинация взаимодействия 2ух объектов / обработок:
- Обработка "Дескриптор выборки". Служит обеткой для функции выполняющий запрос данных, с возможностью модификации как самого запроса, так и преобразованием результата. На входе принимает запрос, а на выходе отдает результат. "Дескриптор выборки" - это замена функции описанной по типу:
Функция СсылкаСуществует(ПроверяемаяСсылка)
// Проверили параметры, возможен возврат без выполнения запроса
// Проверили параметры, модифицировали текст запроса
// Создали / выполнили запрос
// Обработали результат
Возврат Результат;
КонецФункции
- Обработка "Пакетная выборка данных". На входе принимает обработки "Дескриптор выбоки", объединяет их в коллеции и формирует единый запрос, а на выходе отдает результат общей выборки распределенный по дескрипторам выборки.
Рассмотрим подробнее реализацию на примере:
1. Выполним инициализацию пакетной выборки данных с установкой контейнера вывода.
Контейнер вывода - это структура, соответствие или объект в свойства/реквизиты которых необходимо установить результат выполнения определенного дескриптора выборки.
// Определим контейнер вывода
СвойстваИКоллекции = Новый Структура;
// Инициализируем пакетную выборку
ПакетнаяВыборкаДанных = Обработки.сп_ПакетнаяВыборкаДанных.Инициализировать();
ПакетнаяВыборкаДанных.КонтейнерВыводаУстановить(СвойстваИКоллекции);
2. Добавим в пакет получение результата функции РаботаСФайламиСлужебный.ФайлРедактируетсяВОблаке.
Функция имеет следующий вид:
// РаботаСФайламиСлужебный
Функция ФайлРедактируетсяВОблаке(Файл)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| СтатусыСинхронизацииФайловСОблачнымСервисом.Файл
|ИЗ
| РегистрСведений.СтатусыСинхронизацииФайловСОблачнымСервисом КАК СтатусыСинхронизацииФайловСОблачнымСервисом
|ГДЕ
| СтатусыСинхронизацииФайловСОблачнымСервисом.Файл = &Файл";
Запрос.УстановитьПараметр("Файл", Файл);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Возврат Истина;
КонецЦикла;
Возврат Ложь;
КонецФункции
Чтобы иметь возможность использовать данную функцию в пакетной выборке её необходимо модифицировать. Добавим новый общий модуль "РаботаСФайламиСлужебныйПакетнаяВыборка" и выполним адаптацию функции под использование дескриптора выбоки.
// РаботаСФайламиСлужебный
Функция ФайлРедактируетсяВОблаке(Файл) Экспорт
// Создадим дескриптор
Дескриптор = РаботаСФайламиСлужебныйПакетнаяВыборка.ФайлРедактируетсяВОблаке_ДескрипторСоздать();
// Заполним параметры
Дескриптор.Параметры.Вставить("Файл", Файл);
// Сформируем результат
Результат = Дескриптор.Исполнить();
Возврат Результат;
КонецФункции
// РаботаСФайламиСлужебныйПакетнаяВыборка
Функция ФайлРедактируетсяВОблаке_ДескрипторСоздать() Экспорт
//
ЗапросТекст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| СтатусыСинхронизацииФайловСОблачнымСервисом.Файл КАК Файл
|{ВЫБРАТЬ
| Файл}
|ИЗ
| РегистрСведений.СтатусыСинхронизацииФайловСОблачнымСервисом КАК СтатусыСинхронизацииФайловСОблачнымСервисом
|ГДЕ
| СтатусыСинхронизацииФайловСОблачнымСервисом.Файл = &Файл_ИдентификаторДескриптора";
Запрос = Новый Запрос(ЗапросТекст);
ДескрипторВыборки = Обработки.сп_ДескрипторВыборки.Инициализировать(Запрос);
ДескрипторВыборки.ОбработчикПослеВыводаДанныхУстановить("ОбработчикПослеВыводаДанныхРезультатНеПустой");
Возврат ДескрипторВыборки;
КонецФункции
Обратите внимание на изменение в тексте запроса, обязательно нужно:
а) Поля выборки добавить в поля построителя
б) Добавить постфикс "_ИдентификаторДескриптора" ко всем параметрам и временным таблицам
По умолчанию, результат дескриптора выборки - это запрос выгруженный в таблицу значений. Если необходимо дополнительно обработать результат, нужно использовать обработчики "ПередВводомДанных" или "ПослеВыводаДанных".
Полученную функцию теперь можно использовать в пакетной выборке данных. Добавим её в контейнер вывода, с указанием адреса размещения результата - "РедактируетсяВОблаке".
// РедактируетсяВОблаке
ДескрипторВыборки = РаботаСФайламиСлужебныйПакетнаяВыборка.ФайлРедактируетсяВОблаке_ДескрипторСоздать();
ДескрипторВыборки.Параметры.Вставить("Файл", Файл);
ПакетнаяВыборкаДанных.Добавить(ДескрипторВыборки, "РедактируетсяВОблаке");
3. Добавим в пакетную выборку поизвольный запрос
// КоличествоВложений
ЗапросТекст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(1) КАК КоличествоВложений
|{ВЫБРАТЬ
| КоличествоВложений}
|ИЗ
| Справочник.Файлы КАК Файлы
|ГДЕ
| Файлы.ВладелецФайла = &ВладелецФайла_ИдентификаторДескриптора
| И НЕ Файлы.ПометкаУдаления";
Запрос = Новый Запрос(ЗапросТекст);
Запрос.УстановитьПараметр("ВладелецФайла", ВладелецФайла);
ДескрипторВыборки = Обработки.сп_ДескрипторВыборки.Инициализировать(Запрос);
ПакетнаяВыборкаДанных.Добавить(ДескрипторВыборки, "*");
В качестве адреса размещения результата указали "*" - это означает что все колонки последней строки выборки будут установлены в контейнер вывода. В нашем случае в стуктуру "СвойстваИКоллекции", будет добавлен новый ключ "КоличествоВложений" со значением из последней строки в колонке "КоличествоВложений".
4. Заключение
Весь код пакетной выборки будет иметь следующий вид:
//
СвойстваИКоллекции = Новый Структура;
// Инициализируем пакетную выборку
ПакетнаяВыборкаДанных = Обработки.сп_ПакетнаяВыборкаДанных.Инициализировать();
ПакетнаяВыборкаДанных.КонтейнерВыводаУстановить(СвойстваИКоллекции);
// РедактируетсяВОблаке
ДескрипторВыборки = сп_НесоответствияПакетнаяВыборка.ФайлРедактируетсяВОблаке_ДескрипторСоздать();
ДескрипторВыборки.Параметры.Вставить("Файл", Файл);
ПакетнаяВыборкаДанных.Добавить(ДескрипторВыборки, "РедактируетсяВОблаке");
// КоличествоВложений
ЗапросТекст =
"ВЫБРАТЬ
| КОЛИЧЕСТВО(1) КАК КоличествоВложений
|{ВЫБРАТЬ
| КоличествоВложений}
|ИЗ
| Справочник.Файлы КАК Файлы
|ГДЕ
| Файлы.ВладелецФайла = &ВладелецФайла_ИдентификаторДескриптора
| И НЕ Файлы.ПометкаУдаления";
Запрос = Новый Запрос(ЗапросТекст);
Запрос.УстановитьПараметр("ВладелецФайла", ВладелецФайла);
ДескрипторВыборки = Обработки.сп_ДескрипторВыборки.Инициализировать(Запрос);
ПакетнаяВыборкаДанных.Добавить(ДескрипторВыборки, "*");
// Выполним пакетную выборку данных и заполним контейнер вывода
ПакетнаяВыборкаДанных.Исполнить()
Текст запроса, который будет выполнен:
"ВЫБРАТЬ
| NULL КАК Поле0,
| NULL КАК ИдентификаторВыборки
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ ПЕРВЫЕ 1
| СтатусыСинхронизацииФайловСОблачнымСервисом.Файл,
| ""0590fab2d98d4b3f870ee5c2accb3c73""
|ИЗ
| РегистрСведений.СтатусыСинхронизацииФайловСОблачнымСервисом КАК СтатусыСинхронизацииФайловСОблачнымСервисом
|ГДЕ
| СтатусыСинхронизацииФайловСОблачнымСервисом.Файл = &Файл_0590fab2d98d4b3f870ee5c2accb3c73
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| КОЛИЧЕСТВО(1),
| ""2fc374c8272e46b58cf0d23b4df7b185""
|ИЗ
| Справочник.Файлы КАК Файлы
|ГДЕ
| Файлы.ВладелецФайла = &ВладелецФайла_2fc374c8272e46b58cf0d23b4df7b185
| И НЕ Файлы.ПометкаУдаления"
Что в итоге мы имеем:
1. Замеры времени выполнения показали -10% на не нагруженной тестовой базе при выполнении пакетной выборки из 18 коротких запросов. В абсолютном значении - это 0,014 сек. ;)
2. Как минимум еще одна причина, по которой запрос уже давно пора обернуть в обработку и не обращаться к нему напрямую.
3. Отличный повод провести рефакторинг, еще -40% чисто исправили старые ошибки.
Как видите, все просто, данная разработка в помощь!
Обработка является частью модуля Стандартные подсистемы.
Проект и исходный код доступен на GitLab.
-----
Требования:
- Обработка предназначена для версии платформы >= 8.3.13, тестировалась на 8.3.27.1644
-----
Ссылки:
- Проект в GitLab
Проверено на следующих конфигурациях и релизах:
- 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.11.215
Вступайте в нашу телеграмм-группу Инфостарт