Насколько оптимально использование вложенного запроса в поле выборки динамического списка 1С?

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

При разработке конфигураций на платформе 1С:Предприятие 8 мы часто сталкиваемся с необходимостью вывода дополнительных данных в списки документов. В типовых конфигурациях, таких как Зарплата и Управление Персоналом, нередко можно встретить конструкции, где внутри поля выборки запроса размещается вложенный подзапрос. Давайте разберем, насколько это эффективно, как это работает на уровне СУБД и стоит ли опасаться снижения производительности.

Понимание работы коррелированного подзапроса

В примере из темы мы видим конструкцию, которая проверяет наличие записи в регистре сведений для каждой строки основного списка:


ВЫБОР
    КОГДА ИСТИНА В
        (ВЫБРАТЬ ПЕРВЫЕ 1
            ИСТИНА
        ИЗ
            РегистрСведений.ОплатаВедомостейНаВыплатуЗарплаты КАК ОплатаВедомостейНаВыплатуЗарплаты
        ГДЕ
            ОплатаВедомостейНаВыплатуЗарплаты.Ведомость = ЖурналДокументовВедомостиНаВыплатуЗарплаты.Ссылка)
    ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ЕстьОплаты

На первый взгляд кажется, что для каждой строки списка сервер будет выполнять отдельный запрос к таблице регистра, что может привести к катастрофическому замедлению. Однако важно понимать, что современные оптимизаторы SQL (например, MS SQL Server) обладают достаточным уровнем «интеллекта», чтобы оптимизировать подобные конструкции.

Почему это работает быстрее, чем кажется

В подавляющем большинстве случаев оптимизатор СУБД не выполняет подзапрос «в лоб» для каждой строки. Вместо этого он преобразует коррелированный запрос в более эффективную операцию соединения, такую как Left Semi Join или Left Anti Semi Join. Это позволяет серверу обрабатывать данные наборами, а не итеративно.

Тем не менее, для того чтобы эта магия оптимизации сработала, должны соблюдаться определенные условия:

  1. Наличие индексов: Это самый критический фактор. В приведенном примере поле Ведомость в таблице РегистрСведений.ОплатаВедомостейНаВыплатуЗарплаты обязательно должно быть проиндексировано. Если индекс отсутствует, SQL-сервер будет вынужден выполнять полное сканирование таблицы (Table Scan) для каждой строки, что мгновенно сделает интерфейс «неотзывчивым».
  2. Ограничение данных: Использование конструкции ПЕРВЫЕ 1 внутри подзапроса помогает оптимизатору понять, что нам не нужно выбирать все записи, а достаточно найти лишь первый факт соответствия. Это позволяет прекратить поиск сразу после обнаружения первой записи.

Когда стоит избегать такой конструкции

Несмотря на то, что использование подзапросов в поле выборки является допустимым приемом, существуют ситуации, когда от них лучше отказаться в пользу других архитектурных решений:

Рекомендации по оптимизации

Если вы столкнулись с медленной работой динамического списка, мы рекомендуем выполнить следующие шаги:

  1. Проанализируйте план выполнения запроса: Используйте средства СУБД (например, SQL Server Management Studio) для анализа плана выполнения. Если вы видите операцию Table Scan или Clustered Index Scan на большой таблице, это прямой сигнал к необходимости создания индекса.
  2. Используйте временные таблицы: Если запрос получается слишком сложным, стандартом индустрии 1С является использование механизма временных таблиц. Загрузите данные в ВременныеТаблицы, проиндексируйте их, и выполните итоговое соединение с основной таблицей. Это дает СУБД наиболее точное понимание структуры данных и позволяет построить оптимальный план выполнения.
  3. Минимизируйте выборку: Убедитесь, что динамический список настроен на использование механизма постраничного вывода (если это применимо к задаче).

Подводя итог: использование подзапросов в полях выборки — это стандартный инструмент разработчика 1С. В типовых конфигурациях он используется повсеместно и, как правило, хорошо оптимизирован. Главное — помнить об индексах и не злоупотреблять тяжелыми операциями внутри таких подзапросов. Если же производительность все-таки вызывает нарекания, временные таблицы всегда придут на помощь.

← На главную