Информационные системы на платформе 1С широко используются в России и СНГ для автоматизации бизнеса. Однако для эффективной работы системы требуют грамотной настройки запросов, фильтров и отчетов. В этой статье мы подробно разберем примеры использования вложенных запросов в 1С и способы их оптимизации.
Обзор возможностей языка запросов 1С
Язык запросов в системе 1С имеет давнюю историю. Первые его реализации появились в конфигурациях на платформе 7.7 еще в 1990-х годах. С тех пор функциональность запросов значительно расширилась, а синтаксис претерпел множество изменений.
Основными объектами в запросах 1С являются:
- Таблицы (например, справочники или документы);
- Регистры сведений и накопления;
- Реквизиты и свойства объектов;
- Переменные и параметры.
Данные в таблицах имеют иерархическую реляционную структуру. Они могут содержать ссылки на другие таблицы, что позволяет организовывать связи между объектами.
Основные виды запросов в 1С:
- Запросы на выборку данных.
- Запросы с параметрами.
- Запросы с группировкой и агрегацией.
- Иерархические и рекурсивные запросы.
Вложенные запросы в 1С
Вложенным называется запрос, который используется внутри другого запроса. Обычно он заключается в круглые скобки и выступает в роли подзапроса по отношению к основному запросу.
Отличие вложенного запроса от других типов в том, что его результаты доступны только в контексте запроса верхнего уровня. В отличие от это временные таблицы могут передаваться между запросами и повторно использоваться в пакетах.
Рассмотрим пример синтаксиса простого вложенного запроса в операторе ВЫБРАТЬ:
ВЫБРАТЬ (ВЫБРАТЬ СУММА(Количество) ОТ КАЖДОГО Партия КАК ВсегоПартий) КАК ОбщаяСумма ИЗ Документ.ПоступлениеТоваров
Здесь внешний запрос выбирает из таблицы документов поле, которое формируется во вложенном запросе с помощью агрегатной функции СУММА.
"запрос в условии запроса 1с" можно также использовать и в операторе ИЗ, например так:
ИЗ (ВЫБРАТЬ Партия, СУММА(Количество) КАК ОбщееКоличество ИЗ Документ.ПоступлениеТоваров ГДЕ Товар = &Товар ) КАК ВложенныйЗапрос ГДЕ ВложенныйЗапрос.ОбщееКоличество > 100
Здесь подзапрос формирует выборку с группировкой, а внешний запрос накладывает на нее дополнительные условия фильтрации.
Кроме вышеприведенных операторов, вложенные запросы могут использоваться в секциях ОБЛАСТЬ, СГРУППИРОВАТЬ ПО, ИМЕЮЩИЕ и других.
Рекомендации по оптимизации
Несмотря на гибкость и универсальность, вложенные запросы в 1С могут создавать проблемы с производительностью. Это связано с особенностями работы оптимизатора плана выполнения запросов в СУБД.
Для анализа запроса можно воспользоваться специальной функцией в 1С Запрос.Текст
, которая возвращает итоговый SQL-код, позволяющий оценить эффективность работы оптимизатора.
В некоторых случаях вложенные запросы выполняются в сотни раз медленнее аналогичных решений через соединение таблиц или временные таблицы.
"1с запрос условие в списке" - один из распространенных вариантов оптимизации, позволяющий ликвидировать вложенность и ускорить обработку за счет более эффективного плана выполнения запроса.
Другие основные правила написания оптимальных запросов:
- Избегать сложных подзапросов в условиях фильтрации;
- Выносить общие подзапросы во временные таблицы;
- Использовать хранимые процедуры и представления.
Более подробно о практических приемах оптимизации вложенных запросов речь пойдет в следующих разделах.
Практические кейсы и примеры
"условие запросе 1с 8 2" рассмотрим на примере конкретной задачи по оптимизации производительности вложенного запроса в учетной системе на базе 1С:Предприятие 8.2.
Пусть есть запрос партий товаров с дополнительными характеристиками, который использует вложенный подзапрос для отбора параметров из регистра сведений. Изначально запрос выглядел следующим образом:
ВЫБРАТЬ ВложенныйЗапрос.Документ КАК Документ, ВложенныйЗапрос.Параметры КАК Параметры ИЗ (ВЫБРАТЬ индДополнитХарактеристики.Документ, индДополнитХарактеристики.Параметры ИЗ РегистрСведений.индДополнитХарактеристики) КАК ВложенныйЗапрос
Обработка этого запроса занимала порядка 5-8 секунд при больших объемах данных. Для оптимизации воспользуемся вынесением подзапроса во временную таблицу:
ВЫБРАТЬ ДопПараметры.Документ, ДопПараметры.Параметры ИЗ ВременнаяТаблица.ДопПараметры КАК ДопПараметры ; ВЫБРАТЬ индДополнитХарактеристики.Документ, индДополнитХарактеристики.Параметры ПОМЕСТИТЬ ВременнаяТаблица.ДопПараметры ИЗ РегистрСведений.индДополнитХарактеристики
После этого время выполнения запроса снизилось до 1-2 секунд, то есть произошло 4-5 кратное ускорение.
Рекомендации по рефакторингу на основе кейсов
Данный пример наглядно демонстрирует один из эффективных приемов оптимизации вложенных запросов в 1С 8.2 - вынесение подзапросов во временные таблицы с последующим использованием.
Основные шаги по рефакторингу:
- Выделить вложенные запросы.
- Заменить их на временные таблицы.
- В osnovnom запросе использовать временные таблицы.
- Сравнить производительность до/после.
Данный метод позволяет избавиться от избыточных обращений к БД в рамках вложенных запросов и существенно повысить быстродействие.
Примеры готовых решений для распространенных задач
Рассмотрим еще несколько примеров вложенных запросов в 1С и варианты их оптимизации для распространенных задач.
Задача: получить данные из нескольких документов, отфильтрованные по параметрам
Решение:
ВЫБРАТЬ ВнешнийЗапрос.НомерДокумента, ВнешнийЗапрос.Дата ИЗ (ВЫБРАТЬ Документ.Номер КАК НомерДокумента, Документ.Дата КАК Дата ИЗ Документ.ПриходТовара ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ Документ.Номер КАК НомерДокумента, Документ.Дата КАК Дата ИЗ Документ.РасходТовара) КАК ВнешнийЗапрос ГДЕ ВнешнийЗапрос.Дата МЕЖДУ (&ДатаНачала И &ДатаОкончания)
Здесь используется объединение нескольких документов во вложенном запросе с последующей фильтрацией по датам.
Условие в связи запроса 1с
Еще один распространенный прием при работе со связанными документами в 1С - использование вложенных запросов для отбора и фильтрации.
ВЫБРАТЬ ВнешнийЗапрос.Номер КАК НомерЗаказа, ВнешнийЗапрос.Номенклатура КАК Номенклатура ИЗ (ВЫБРАТЬ Заказ.Номер КАК НомерЗаказа, ТоварыЗаказа.Номенклатура КАК Номенклатура ИЗ Документ.Заказ КАК Заказ ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ТоварыЗаказа КАК ТоварыЗаказа ПО Заказ.Ссылка = ТоварыЗаказа.Ссылка) КАК ВнешнийЗапрос ГДЕ ВнешнийЗапрос.НомерЗаказа В(&СписокЗаказов)
Здесь связанные документы объединяются во вложенном запросе, а затем на результат накладывается дополнительный фильтр по списку номеров заказов.