В языке запросов реализована возможность получения поля через точку от другого поля. С одной стороны, эта возможность позволяет создавать компактные запросы, однако, с другой стороны, всегда следует понимать, что стоит за каждым таким действием. В данном разделе будет рассказано, что происходит при получении поля через точку, и будут даны рекомендации для оптимизации доступа к полям.
Рассмотрим следующий запрос:
Копировать в буфер обменаВЫБРАТЬ
Номенклатура.Наименование,
КоличествоОборот
ИЗ
РегистрНакопления.УчетНоменклатуры.Обороты КАК УчетНоменклатурыОбороты
В этом запросе поле «Наименование» получается через точку от поля «Номенклатура». При исполнении такого запроса язык запросов 1С:Предприятия создаст неявное соединение со справочником «Номенклатура», и будет получать поле «Наименование» из него. Таким образом, реальный запрос, который будет исполняться, будет аналогичен следующему:
Копировать в буфер обменаВЫБРАТЬ
СправочникНоменклатура.Наименование,
КоличествоОборот
ИЗ
РегистрНакопления.УчетНоменклатуры.Обороты КАК УчетНоменклатурыОбороты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СправочникНоменклатура
ПО УчетНоменклатурыОбороты.Номенклатура = СправочникНоменклатура.Ссылка
Следует отметить, что если в запросе происходит получение нескольких полей через точку от одного поля, то соединение с таблицей, на которую ссылаются поля через точку, будет создано одно. Например, если в первом примере мы будем получать не только поле «Наименование», но и поле «Код» через точку от поля «Номенклатура», будет создано одно, а не два соединения с таблицей «Номенклатура».
Не следует получать поле «Ссылка» через точку от другого поля. При таком способе получения поля «Ссылка» будет создаваться дополнительное соединение, которое, скорее всего, замедлит выполнение запроса.
Например, в следующем запросе поле «Ссылка» получается через точку от поля «Контрагент»:
Копировать в буфер обменаВЫБРАТЬ
РасходнаяНакладная.Дата,
РасходнаяНакладная.Номер
ИЗ
Документ.РасходнаяНакладная КАК РасходнаяНакладная
ГДЕ
РасходнаяНакладная.Контрагент.Ссылка = &Контрагент
В результате будет создано совершенно ненужное в данном случае соединение с таблицей «Контрагенты» и, как следствие, выполнение запроса, скорее всего, замедлится. Такой запрос следует переписать следующим образом:
Копировать в буфер обменаВЫБРАТЬ
РасходнаяНакладная.Дата,
РасходнаяНакладная.Номер
ИЗ
Документ.РасходнаяНакладная КАК РасходнаяНакладная
ГДЕ
РасходнаяНакладная.Контрагент = &Контрагент
Если поле, через которое получается другое поле, является ссылкой на несколько таблиц, то при выполнении запроса будет осуществлено столько соединений, в скольких ссылаемых таблицах будет найдено требуемое поле.
Пример. Пусть поле «Регистратор» регистра накопления ссылается на два документа: «РасходнаяНакладная» и «ПриходнаяНакладная». В таком случае следующий запрос:
Копировать в буфер обменаВЫБРАТЬ
УчетНоменклатуры.Регистратор.Номер,
УчетНоменклатуры.Количество
ИЗ
РегистрНакопления.УчетНоменклатуры КАК УчетНоменклатуры
даст неявное соединение с обеими таблицами документов, то есть будет выполнено два соединения. Исполняемый запрос будет выглядеть приблизительно так:
Копировать в буфер обменаВЫБРАТЬ
ВЫБОР
КОГДА УчетНоменклатуры.Регистратор ССЫЛКА Документ.ПриходнаяНакладная
ТОГДА ПриходнаяНакладная.Номер
КОГДА УчетНоменклатуры.Регистратор ССЫЛКА Документ.РасходнаяНакладная
ТОГДА РасходнаяНакладная.Номер
КОНЕЦ,
УчетНоменклатуры.Количество
ИЗ
РегистрНакопления.УчетНоменклатуры КАК УчетНоменклатуры
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПриходнаяНакладная КАК ПриходнаяНакладная
ПО УчетНоменклатуры.Регистратор = ПриходнаяНакладная.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РасходнаяНакладная КАК РасходнаяНакладная
ПО УчетНоменклатуры.Регистратор = РасходнаяНакладная.Ссылка
Если же поле, через которое получается другое поле, является любой ссылкой, то возможны ситуации, при которых будет происходить неявное соединение со всеми объектными таблицами конфигурации. Так, например, если мы получаем от поля типа «любая ссылка» поле «Представление», а в нашей конфигурации присутствует 50 справочников и 100 документов, то будет произведено 150 соединений с различными таблицами.
На это стоит обращать внимание при разработке структуры данных, также об этом следует помнить при составлении запросов.
Иногда, при составлении запроса известно, какая ссылка будет находиться в том или ином поле, ссылающемся на несколько таблиц. В этом случае можно явно указать в запросе нужную таблицу для того, чтобы неявное соединение выполнялось только с указанной таблицей, а не со всеми таблицами, на которые ссылается данное поле.
Пример. Пусть поле «Регистратор» регистра накопления ссылается на два документа: «РасходнаяНакладная» и «ПриходнаяНакладная», и в предложении «ГДЕ» выборка ограничивается только значениями регистратора, ссылающимися на «РасходнуюНакладную»:
Копировать в буфер обменаВЫБРАТЬ
УчетНоменклатуры.Регистратор.Номер,
УчетНоменклатуры.Количество
ИЗ
РегистрНакопления.УчетНоменклатуры КАК УчетНоменклатуры
ГДЕ
УчетНоменклатуры.Регистратор ССЫЛКА Документ.РасходнаяНакладная
Так как в данном запросе мы четко знаем, что в результат попадут только документы, у которых регистратор ссылается на таблицу расходных накладных, мы можем несколько доработать запрос для того, чтобы он выполнялся более эффективно:
Копировать в буфер обменаВЫБРАТЬ
ВЫРАЗИТЬ(УчетНоменклатуры.Регистратор КАК Документ.РасходнаяНакладная).Номер,
УчетНоменклатуры.Количество
ИЗ
РегистрНакопления.УчетНоменклатуры КАК УчетНоменклатуры
ГДЕ
УчетНоменклатуры.Регистратор ССЫЛКА Документ.РасходнаяНакладная
При исполнении такого запроса будет создано соединение лишь с таблицей «Документ.РасходнаяНакладная», вместо соединения с обеими таблицами, на которые ссылается поле «Регистратор». Это положительно повлияет на скорость выполнения запроса.