Получение полей через точку в запросе

09 марта 2013

Конфигурация с примером из статьи

Пишем простой запрос

В тестовой конфигурации, в которой будем реализовывать все примеры в статье, создадим документ "Продажа" и три справочника: "Номенклатура", "ЕдиницыИзмерения" и "БазовыеЕдиницы". Справочник "ЕдиницыИзмерения" подчинен справочнику "Номенклатура". В документе продажи три реквизита: "Номенклатура", "ЕдиницаИзмерения" и "Количество". Первые два ссылаются на элемент соответствующего справочника, "Количество" - числовое поле.

Структура метаданных тестовой конфигурации

Чтобы проанализировать действия платформы напишем два простых запроса. Первый запрос будет производить выборку ссылки, а также поля "Номенклатура" и "ЕдиницаИзмерения" из документа "Продажи":

ТекстЗапроса = "ВЫБРАТЬ 
  | Продажа.Ссылка, 
  | Продажа.Номенклатура, 
  | Продажа.ЕдиницаИзмерения
  |ИЗ 
  | Документ.Продажа КАК Продажа"
Второй запрос будет использовать возможности платформы для выборки полей через "точку" в запросе. Чтобы усложнить пример, сделаем выборку в несколько уровней. В качестве результатирующих полей выборки сделаем ссылку на документ и следующие поля: "Номенклатура", "ЕдиницаИзмерения", "БазоваяЕдиница", "НаименованиеБазовойЕдиницы", "КодБазовойЕдиницы". Текст запроса будет выглядеть следующим образом:
ТекстЗапроса = "ВЫБРАТЬ 
        | Продажа.Ссылка, 
        | Продажа.Номенклатура, 
        | Продажа.ЕдиницаИзмерения, 
        | Продажа.ЕдиницаИзмерения.БазоваяЕдиница 
               |                             КАК БазоваяЕдиница, 
        | Продажа.ЕдиницаИзмерения.БазоваяЕдиница.Код 
               |                             КАК КодБазовойЕдиницы, 
        | Продажа.ЕдиницаИзмерения.БазоваяЕдиница.Наименование 
               |                             КАК ИмяБазовойЕдиницы
        |ИЗ
        | Документ.Продажа КАК Продажа"
Результаты выполнения обоих запросов в соответствии с тестовыми данными выглядят следующим образом:
Результаты запросов

Как мы видим, оба запроса отлично работают. Теперь рассмотрим поведение платформы 1С:Предприятие 8.x, а именно формирование SQL-запроса к СУБД при использовании обращения к полям через "точку" в запросе.

Что делает платформа?

При выполнении первого запроса, 1С:Предприятие формирует достаточно простой SQL-запрос:

querySQL = "SELECT 
    | T1._IDRRef, // Ссылка
    | T1._Fld30RRef, // Номенклатура
    | T1._Fld31RRef // ЕдиницаИзмерения
    |FROM 
    | _Document28 T1 WITH(NOLOCK)"
В запросе все необходимые данные получаются из одного запроса, поэтому нет необходимости формировать выборки из других таблиц. Если же мы посмотрим на сформированный SQL-запрос для второго примера, картина будет совсем иной:
querySQL = "SELECT
    | T1._IDRRef, // Ссылка 
    | T1._Fld30RRef, // Номенклатура
    | T1._Fld31RRef, // Единица измерения 
    | T2._Fld29RRef, // Базовая единица
    | T3._Code,  // Код базовой единицы
    | T3._Description // Наименование базовой единицы
    |FROM 
    | _Document28 T1 WITH(NOLOCK) // Таблица документа ""Продажа""
    |  LEFT OUTER JOIN 
    |// Присоединение спр. ""Единицы измерения"" для базовой единицы
    | _Reference26 T2 WITH(NOLOCK)ON T1._Fld31RRef = T2._IDRRef 
    |  LEFT OUTER JOIN 
    |//Присоединение спр. ""Базовые единицы"" для наименования и кода
    | _Reference27 T3 WITH(NOLOCK)ON T2._Fld29RRef = T3._IDRRef 
    |" 

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

Плюсы и минусы

Возможности платформы 1С:Предприятия 8.x по построению выборки в запросах через "точку" позволяют упростить построение запросов к базе данных для разработчиков, причем весьма значительно. Согласитеcь, легче написать в тексте поле через точку от ссылочного типа, чем добавлять, хоть и конструктором, новую таблицу в запрос и прописывать условия соединения. К тому же, это возможность позволяет значительно расширить возможности при настройке отчетов, выводимых полей и прочего. В этом и заключается огромный плюс.

Но есть и другая сторона. Избыточное использование подобной возможности в запросах может значительно повысить нагрузку на сервер СУБД. Все будет зависеть от конкретного запроса. Можно лишь сказать, что нужно стремиться получать выборки данных более оптимальным образом из меньшего количества таблиц.

Небольшой итог

Подведем небольшой итог. Во-первых, использование обращений через "точку" в запросе обрабатываются более оптимально, чем подобные обращения для объектной модели работы с данными. Ранее я писал об этом в одной из статей. Во-вторых, использование подобной возможности значительно ускоряет процесс написания запросов и расширяет возможности настройки отчетов в пользовательском режиме.

При умелом обращении с данным механизмом отрицательное влияние на производительность будет сводиться к нулю. Поэтому не использовать его будет просто не рациональным шагом.


comments powered by Disqus