358 документов
← К списку

Обращения к виртуальным таблицам

страница

#std657

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1. При использовании виртуальных таблиц в запросах, следует передавать в параметры таблиц все условия, относящиеся к данной виртуальной таблице. Не рекомендуется обращаться к виртуальным таблицам при помощи условий в секции ГДЕ и т.п.

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

Например, следующий запрос использует секцию ГДЕ запроса для выборки из виртуальной таблицы:

Запрос.Текст = "ВЫБРАТЬ
| Номенклатура
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки()
|ГДЕ
| Склад = &Склад";

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

Рекомендуется ограничивать количество выбираемых записей на самом раннем этапе обработки запроса. Для этого следует передать условия в параметры виртуальной таблицы. 

Запрос.Текст = "ВЫБРАТЬ
| Номенклатура
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, Склад = &Склад)";

2.1. При обращении к виртуальной таблице следует передавать в условия наиболее простые конструкции, например, "Измерение = Значение". Не рекомендуется использовать подзапросы и соединения(*) в параметрах виртуальной таблицы, так как это приводит к медленной работе запроса.

* Примечание: как явные соединения в подзапросах, так и неявные – при обращении к полям «через точку» от ссылки и соединения, добавляемые из ограничений доступа к данным (RLS), предусмотренных в ролях конфигурации.

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

  • в подзапросе только одна таблица, нет соединений с другими таблицами;

  • если в подзапросе таблица табличной части (например, Документ.Накладная.СписокТоваров), то не должно быть обращения к реквизитам таблицы-шапки (Накладная.Проведен);

  • если в подзапросе таблица, у которой могут быть табличные части (например, Документ.Накладная), то не должно быть обращений к табличным частям (например, ГДЕ Документ.Накладная.СписокТоваров.Номенклатура = "1");

  • если в подзапросе временная таблица, то не должно быть условий (раздела ГДЕ);

  • если в подзапросе постоянная таблица, то условие (раздел ГДЕ) допустимо, только если условие выполняется для 80% (или более) случаев; отсутствие условия означает выполнение для 100% случаев.

  • если в подзапросе постоянная таблица, то в ограничениях доступа к данным (RLS) не должно содержатся подзапросов и соединений (допускаются только простые условия вида ГДЕ Реквизит = Значение, "ГДЕ Истина"). Например, при использовании стандартных шаблонов RLS, входящих в состав подсистемы «Управление доступом» Библиотеки стандартных подсистем к запросу неявно добавляется конструкция Exists с несколькими подзапросами и соединениями. В таких случаях следует переписать исходный запрос с использованием временной таблицы или привилегированного режима.

Например, неправильно:

... ИЗ
РегистрНакопления.ТоварыКОтгрузке.Остатки(
&ДатаОтгрузки,
&ОтображениеРаспоряжений
 И ДокументОтгрузки.Склад = &Склад       -- неявное соединение «через точку»
 ИЛИ ДокументОтгрузки В
  (ВЫБРАТЬ                               -- подзапрос с соединением
   Распоряжения.Распоряжение КАК ДокументОтгрузки
  ИЗ
  Документ.ЗаданиеНаПеревозку.Распоряжения КАК Распоряжения –- доступ к этому документу ограничен по сложному RLS, который неявно добавляет еще пару соединений
  ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаданиеНаПеревозку.СкладыПогрузки КАК  СкладыПогрузки
  ПО
  Распоряжения.Ссылка = СкладыПогрузки.Ссылка
  И СкладыПогрузки.Склад = &Склад
  И Распоряжения.Ссылка.Проведен         –- здесь и ниже обращения к реквизитам шапки
  И Распоряжения.Ссылка.Статус В (...)))

правильно:

... ИЗ
РегистрНакопления.ТоварыКОтгрузке.Остатки(
 &ДатаОтгрузки,
 Склад = &Склад                         -- теперь это реквизит регистра
 ИЛИ ДокументОтгрузки В
 (ВЫБРАТЬ
  ЗаданияНаПеревозку.Распоряжение
  ИЗ
  ВременнаяТаблицаЗаданийНаПеревозку КАК ЗаданияНаПеревозку))  -- выборка из временной таблицы без условий

2.3. В случае, если нужно использовать несколько условий с подзапросами, следует выбрать одно, удовлетворяющее условиям выше и отфильтровывающее максимальное количество записей. Остальные условия следует накладывать на внешний запрос.

Кроме того, в ряде случаев можно обойтись и без перемещения условий на внешний запрос, если применять временные таблицы.
Например, вместо условия (неправильно):

Номенклатура В (...) И Характеристика В (...) И Серия В(...)

правильно:

(Номенклатура, Характеристика, Серия) В (ВЫБРАТЬ Номенклатура, Характеристика, Серия ИЗ ВременнаяТаблицаТоваров)

См. также