v8-code-style icon indicating copy to clipboard operation
v8-code-style copied to clipboard

Стандарт 657: Параметры виртуальной таблицы не должны содержать подзапросы

Open marmyshev opened this issue 4 years ago • 1 comments

Название проверки

Напишите краткое название проверки

Английское название проверки

Напишите английское название проверки

Правило анализа кода/метаданных

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

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

Мета-информация (пожалуйста, заполните если знаете):

  • Номер стандарта: 657
  • Код проверки: ql-virtual-table-parameter-subquery
  • Тип ошибки: PERFORMANCE
  • Критичность: MAJOR
  • Код ошибки АПК: нет

Параметры проверки

Текст ошибки

Пример некорректного решения

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

Описание, почему так делать нельзя

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

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

Пример корректного решения

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

Пример некорректного решения

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

Описание, почему так делать нельзя

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

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

Пример корректного решения

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

Дополнительные материалы

marmyshev avatar Oct 01 '21 20:10 marmyshev

взял в работу

disant1 avatar Apr 27 '22 05:04 disant1