Три запроса, позволяющие получить данные табчасти документа и его реквизитов.
Какой из этих запросов обычно вы напишите и какой по вашему мнению более православный (с точки зрения производительности, масштабируемости, феншуя)?
Запрос №1:
Запрос.Текст =
"ВЫБРАТЬ
| ОприходованиеТоваровТовары.Номенклатура КАК Номенклатура,
| ОприходованиеТоваровТовары.Количество КАК Количество,
| ОприходованиеТоваровТовары.Цена КАК Цена,
| ОприходованиеТоваровТовары.Сумма КАК Сумма,
| ОприходованиеТоваровТовары.Ссылка.Склад КАК Склад,
| ОприходованиеТоваровТовары.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры
|ИЗ
| Документ.ОприходованиеТоваров.Товары КАК ОприходованиеТоваровТовары
|ГДЕ
| ОприходованиеТоваровТовары.Ссылка = &Ссылка";
Показать
Запрос №2:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОприходованиеТоваровТовары.Номенклатура КАК Номенклатура,
| ОприходованиеТоваровТовары.Количество КАК Количество,
| ОприходованиеТоваровТовары.Цена КАК Цена,
| ОприходованиеТоваровТовары.Сумма КАК Сумма,
| ОприходованиеТоваров.Склад КАК Склад,
| СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры
|ИЗ
| Документ.ОприходованиеТоваров.Товары КАК ОприходованиеТоваровТовары
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
| ПО ОприходованиеТоваровТовары.Номенклатура = СпрНоменклатура.Ссылка
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОприходованиеТоваров КАК ОприходованиеТоваров
| ПО ОприходованиеТоваровТовары.Ссылка = ОприходованиеТоваров.Ссылка
|ГДЕ
| ОприходованиеТоваровТовары.Ссылка = &Ссылка";
Показать
Запрос №3:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОприходованиеТоваровТовары.Номенклатура КАК Номенклатура,
| ОприходованиеТоваровТовары.Количество КАК Количество,
| ОприходованиеТоваровТовары.Цена КАК Цена,
| ОприходованиеТоваровТовары.Сумма КАК Сумма,
| ОприходованиеТоваров.Склад КАК Склад,
| СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры
|ИЗ
| Документ.ОприходованиеТоваров.Товары КАК ОприходованиеТоваровТовары
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
| ПО ОприходованиеТоваровТовары.Номенклатура = СпрНоменклатура.Ссылка
| И (ОприходованиеТоваровТовары.Ссылка = &Ссылка)
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОприходованиеТоваров КАК ОприходованиеТоваров
| ПО ОприходованиеТоваровТовары.Ссылка = ОприходованиеТоваров.Ссылка
| И (ОприходованиеТоваровТовары.Ссылка = &Ссылка)";
(2) вы про запросы 2 и 3? в них я лезу в справочник Номенклатура, чтобы получить значение реквизита ВидНоменклатуры. Просто тут это в явном виде. В запросе 1 на самом деле точно такое же обращение будет, только его платформа сама допишет.
Просто тут это в явном виде. В запросе 1 на самом деле точно такое же обращение будет, только его платформа сама допишет.
Наверное надо смотреть в какие запросы будут преобразованы эти 3 варианта, а то как бы не оказалось что в итоге на СУБД будет выполнен один и тот же запрос, после преобразования.
(5) ну в теории они и должны быть преобразованы в один и тот же запрос. но просто есть вероятность, при определенных условиях, вид запроса №1 который дойдет до БД может меняться.
Если рассматривать все три варианта, как они есть - то они конечно же идентичны.
Но всегда надо учитывать перспективы развития. Все неявности - это потенциальная угроза, и их надо избегать. Все ненужные повторы (это в варианте 3) - также потенциальная угроза.
Точно не третий.
Условие в соединении (если СУБД не догадается внести условие в предикат) вынудит получить для мержа всю таблицу. И если у вас транзакция, то это или лишние s блокировки, или лишняя нагрузка на темп при rcsi. (Речь не про конкретно данный случай и mssql, а вообще про такой подход. Условия в ГДЕ - лучше, чем в соединении).
Что говорить.... Смотрите планы.
Первые два - без разницы. СУБД их выполнит одинаково.
Явные соединения нужны при составных типах. Остальное - нагрузка на руки и клавиатуру.
Писать нужно просто, чтобы код легко дорабатывался.
А для производительности - получите сертификат эксперта. Тогда все станет на свои места.
(14) нужно смотреть план запроса.
СУБД может не согласиться с задумками программиста или даже с самой 1с и сделать все по своему)) Мир полон неожиданностей)
Вообще, да. При первичном получении данных из индекса будут учтены только условия ГДЕ.
СУБД потом все равно преобразует этот запрос в SQL. В первом варианте это
| ОприходованиеТоваровТовары.Ссылка.Склад КАК Склад,
| ОприходованиеТоваровТовары.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры
будет дополнено к основному запросу левым соединением с таблицей склады и видом номенклатуры.
Остальные 2 лишняя нагрузка, третий вообще жесть. :)
Если нет никаких составных полей, то первый запрос норм. Если есть составные, то нужно использовать ВЫРАЗИТЬ.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОприходованиеТоваровТовары.Номенклатура КАК Номенклатура,
| ОприходованиеТоваровТовары.Количество КАК Количество,
| ОприходованиеТоваровТовары.Цена КАК Цена,
| ОприходованиеТоваровТовары.Сумма КАК Сумма,
| ОприходованиеТоваров.Склад КАК Склад,
| СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры
|ИЗ
| Документ.ОприходованиеТоваров КАК ОприходованиеТоваров
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.ОприходованиеТоваров.Товары КАК ОприходованиеТоваровТовары
| ПО ОприходованиеТоваровТовары.Ссылка = ОприходованиеТоваров.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
| ПО ОприходованиеТоваровТовары.Номенклатура = СпрНоменклатура.Ссылка
|
|ГДЕ
| ОприходованиеТоваров .Ссылка = &Ссылка";
Мне кажется, что это простой пример, где прекрасно пройдет разыменование. И 1с разработчику удобно читать, и голову даю на отсечение, 1с справится с переводом этого запроса на SQL.
А вот давайте поговорим лучше про обращения к регистру накоплений с парочкой условий в самом регистре накоплений и условий на полученный результат. И мы тут замучаемся спорить)
1. Зачем городить огород?
Если поле, к которому обращаюсь через "." ссылается на N таблиц, то использую соединение, либо через выразить. В остальных случаях не вижу проблем с обращением к таким полям, 1с интерпретирует как надо (https://its.1c.ru/db/metod8dev#content:2662:hdoc), это упрощает написание запросов, они становятся менее громоздкими и в следствие более читабельными.
Можно и несколько раз обращаться через точку, главное - чтобы это не было поле составного типа (а точнее - не ссылалось на N таблиц, ведь, если поле содержит, к примеру, ссылку или строку, то тут будет однозначность при обращении).