bsl-language-server icon indicating copy to clipboard operation
bsl-language-server copied to clipboard

[NEW] Обращение через точку к полям ссылочных реквизитов временной таблицы

Open agibalovsa opened this issue 2 years ago • 9 comments

Описание проблемы, ошибки, которую надо диагностировать

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

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

Ссылка на источник, подтверждающее нарушение либо обоснование наличия проблемы

Нет.

Параметры диагностики

Тип Статья на русском

  • [ ] :ant: Ошибка
  • [ ] :cop: Уязвимость
  • [x] :guardsman: Потенциальная уязвимость
  • [ ] :poop: Качество кода
  • [ ] :trollface: Другое

Важность Статья на русском

  • [ ] :broken_heart: Блокирующая / Blocker
  • [ ] :heart: Критическая / Critical
  • [x] :yellow_heart: Важная / Major
  • [ ] :blue_heart: Незначительная / Minor
  • [ ] :green_heart: Информационная / Info
  • [ ] :revolving_hearts: Другое

Тэги Статья на русском

  • [ ] STANDARD - "Нарушение стандартов 1С"
  • [ ] LOCKINOS - "Не будет работать в другой ОС"
  • [ ] SQL - "Проблема с запросом"
  • [x] PERFORMANCE - "Проблема производительности"
  • [ ] BRAINOVERLOAD - "Непонятный код"
  • [x] BADPRACTICE - "Плохая практика программирования"
  • [ ] CLUMSY - "Излишние действия"
  • [ ] DESIGN - "Ошибка в проектировании"
  • [ ] SUSPICIOUS - "Подозрительный код"
  • [ ] UNPREDICTABLE - "Непредсказуемо работающий код"
  • [ ] DEPRECATED - "Устаревшая функциональность"
  • [ ] ERROR - "Ошибочная конструкция"
  • [ ] LOCALIZE - "Проблемы локализации"

Время на исправление (минут)

15

Дополнительная информация

Пример:

ВЫБРАТЬ
	ЗаказКлиентаТовары.Ссылка КАК ЗаказКлиента,
	ЗаказКлиентаТовары.Номенклатура КАК Номенклатура,
	ЗаказКлиентаТовары.Характеристика КАК Характеристика,
	ЗаказКлиентаТовары.Цена КАК Цена,
	ЗаказКлиентаТовары.Упаковка КАК Упаковка
ПОМЕСТИТЬ ВТ_ТоварыЗаказов
ИЗ
	Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
ГДЕ
	ЗаказКлиентаТовары.Ссылка В(&Заказы)

ИНДЕКСИРОВАТЬ ПО
	Номенклатура,
	Характеристика,
	Упаковка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
	ЦеныНоменклатурыСрезПоследних.Характеристика КАК Характеристика,
	ЦеныНоменклатурыСрезПоследних.Цена КАК Цена,
	ЦеныНоменклатурыСрезПоследних.Валюта КАК Валюта,
	ЦеныНоменклатурыСрезПоследних.Упаковка КАК Упаковка
ПОМЕСТИТЬ ВТ_МаксимальныеЦены
ИЗ
	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
			,
			(Номенклатура, Характеристика) В
				(ВЫБРАТЬ
					ВТ_ТоварыЗаказов.Номенклатура КАК Номенклатура,
					ВТ_ТоварыЗаказов.Характеристика КАК Характеристика
				ИЗ
					ВТ_ТоварыЗаказов КАК ВТ_ТоварыЗаказов)) КАК ЦеныНоменклатурыСрезПоследних
ГДЕ
	ЦеныНоменклатурыСрезПоследних.ВидЦены = &МаксимальнаяЦена

ИНДЕКСИРОВАТЬ ПО
	Номенклатура,
	Характеристика,
	Валюта,
	Упаковка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ_ТоварыЗаказов.ЗаказКлиента КАК ЗаказКлиента,
	ВТ_ТоварыЗаказов.ЗаказКлиента.Партнер КАК Партнер,
        ВТ_ТоварыЗаказов.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры ,
	ВТ_ТоварыЗаказов.Номенклатура КАК Номенклатура,
	ВТ_ТоварыЗаказов.Характеристика КАК Характеристика,
	ВТ_ТоварыЗаказов.Цена > ВТ_МаксимальныеЦены.Цена КАК ПревышенаМаксимальнаяЦена
ИЗ
	ВТ_ТоварыЗаказов КАК ВТ_ТоварыЗаказов
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_МаксимальныеЦены КАК ВТ_МаксимальныеЦены
		ПО ВТ_ТоварыЗаказов.Номенклатура = ВТ_МаксимальныеЦены.Номенклатура
			И ВТ_ТоварыЗаказов.Характеристика = ВТ_МаксимальныеЦены.Характеристика
			И ВТ_ТоварыЗаказов.ЗаказКлиента.Валюта = ВТ_МаксимальныеЦены.Валюта
			И ВТ_ТоварыЗаказов.Упаковка = ВТ_МаксимальныеЦены.Упаковка
ГДЕ
	ВТ_ТоварыЗаказов.Номенклатура.ВидНоменклатуры = &ВидНоменклатуры 

Проверка должна сообщить:

  1. соединение "ВТ_ТоварыЗаказов.ЗаказКлиента.Валюта = ВТ_МаксимальныеЦены.Валюта" не корректно, т.к. поле "Валюта " необходимо получать во временной таблице "ВТ_ТоварыЗаказов".

    Исправив эту ситуацию. можно сделать более эффективный индекс, включив в него валюту.

  2. получение поля "ВТ_ТоварыЗаказов.ЗаказКлиента.Партнер" не корректно, его необходимо перенести во временную таблицу "ВТ_ТоварыЗаказов".

    Выполнив это условие мы сократим число обращений к таблице "ЗаказКлиента" с 2х до 1го (с условием того, если Валюту мы уже получаем во временной таблице).

  3. построен фильтр по вложенному полю из временной таблицы "ВТ_ТоварыЗаказов.Номенклатура.ВидНоменклатуры", необходимо перенести получение поля во временную таблицу "ВТ_ТоварыЗаказов", и проверить, что наложенный фильтр оптимальный

    В данном случае сразу несколько ошибок

    1. фильтр не в корректном месте, в общем случае его оптимальней перенести во временную таблицу, это будет очевидней, если и поле "ВидНоменклатуры" мы будем получать во временной таблице
    2. Если запрос будет в СКД, а поле ВидНоменклатуры мы получим в конечном запросе, то при наложении фильтра на вид номенклатуры, мы получим опять же не оптимальный фильтр, поэтому нужно либо вообще вид номенклатуры не получать в запросе, тогда СКД его наложит автоматически в первую ВТ, либо поле "ВидНоменклатуры" получать во временной таблице "ВТ_ТоварыЗаказов", тогда СКД опять же его подхватит.

agibalovsa avatar May 30 '22 15:05 agibalovsa

Нужен какой то формальный алгоритм на что реагировать и ругаться

asosnoviy avatar Jun 02 '22 08:06 asosnoviy

Добавил пример

agibalovsa avatar Jun 02 '22 09:06 agibalovsa

Дописал еще один случай в пример.

agibalovsa avatar Jun 02 '22 10:06 agibalovsa

@agibalovsa почему вдруг потенциальная уязвимость? )

предлагаю качество кода

artbear avatar Jun 17 '22 13:06 artbear

@artbear все же, как мне кажется, качество кода - это больше к его внешнему виду, к его оформлению. В данном же случае возможно падение производительности.

agibalovsa avatar Jun 17 '22 13:06 agibalovsa

Можно вообще и то и другое ))

agibalovsa avatar Jun 17 '22 13:06 agibalovsa

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

Выбрать Т.Ссылка, Т.ЕщеПоле, Т.ДругоеПоле
ИЗ ИсходнаяТаблица КАК Т
ПОМЕСТИТЬ Таблица
ГДЕ Условие;

Выбрать Фильтр.Ссылка КАК СсылкаФильтра
ИЗ Цены.ВиртТаблица((Поле1, Поле2) В (Выбрать * Из Таблица)) КАК Цены
ГДЕ Условие2;

Выбрать Т.ЕщеПоле.Наименование,
Т.ДругоеПоле.Реквизит.Наименование
ИЗ ИсходнаяТаблица КАК Т
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Цены КАК Цены
Условия соединения по полям таблицы

в этом случае правило выдаст ложный результат, что закономерно.

artbear avatar Jun 17 '22 14:06 artbear

@artbear все же, как мне кажется, качество кода - это больше к его внешнему виду, к его оформлению. В данном же случае возможно падение производительности.

уязвимость - это к хакерам, а здесь просто недочет кода, проблемы с качеством, но не явная ошибка. Поэтому и я предлагаю убрать флаг про уязвимость и поставить флаг "качество кода"

artbear avatar Jun 17 '22 14:06 artbear

@artbear

в этом случае правило выдаст ложный результат, что закономерно.

Интересно, заставил задуматься. В 3м запросе в итоге 4 соединения. Какое из них первое?... В смысле в плане запросов, что отыграет сначала, соединение по ценам или другие соединения.

agibalovsa avatar Jun 17 '22 14:06 agibalovsa