Имя: Пароль:
1C
 
1С. Запросы. Как работают соединения? Где почитать?
0 OnNeOn
 
04.12.19
20:51
Привет бро! Прежде чем начинать учить прочти вопрос внимательно.
Как работает левое и внутреннее соединение? Именно не какой получается результат, а как происходит само соединение? Т.е. допустим надо соединить две таблицы Документ Реализация товаров и справочника контрагенты.
Как происходит таинство соития документа и элемента справочника? Поговорим об этом? Кто знает где почитать? или посмотреть? Всем спасибо!

Хорошей среды, с маленькой пятницей вас!
1 Йохохо
 
04.12.19
20:54
если логическое выражение истинно - соединить, иначе - не соединять
2 OnNeOn
 
04.12.19
20:56
(1) Нет, допустип

ВнутреннееСоединение По Документ.Контрагент = СправочникКонтрагенты.Ссылка
3 Asmody
 
04.12.19
20:57
(0) это тебе надо почитать реляционную алгебру. Вот отсюда можешь начать https://m.habr.com/ru/post/145381/
4 OnNeOn
 
04.12.19
20:57
интересно соединение именно с сылочным типом.
5 OnNeOn
 
04.12.19
20:57
(3) ммммм, реляционную, по связям значит
6 OnNeOn
 
04.12.19
21:00
Но ведь все равно. получается что ищется первый элемент, документ, потом получается ссылка на контрагента, вероятно с его кластерным индексом (если он есть у справочника), и перебором ищется наша ссылка в таблице. Правильно я думаю?
7 OnNeOn
 
04.12.19
21:03
(3) А ссылка похожа на статью по ms SQL которую я читаю. Реляционная БД это сила.
8 OnNeOn
 
04.12.19
21:12
Хорошо, тогда вопрос у зубрам, почему внутренее соединение дольше левого соединения выполняется?
9 OnNeOn
 
04.12.19
21:26
Неужели никто не знает как это работает?
10 palsergeich
 
04.12.19
21:32
(9) все зависит от СУБД, 1с просто транслирует текст запроса во внутренних представлениях в представления СУБД.
В случае левого соединения если поля правой таблицы не выводятся движком СУБД применяются оптимизации, в случае внутреннего соединения этого не происходит.
На самом деле ньюансов очень много
11 ДенисЧ
 
04.12.19
21:32
(8) В индексы не попадаешь. Иди изучай SQL и ниии мозги
12 palsergeich
 
04.12.19
21:37
(10) на самом деле вопрос не к 1с а конкретной версии СУБД если запрос с одинаковым результатом при левом и внутреннем соединении имеет разную скорость выполнения.
(6) Это один из физических операторов который nested loops. Но есть ещё hash match join и medge join которые физически совсем по другому работают
13 palsergeich
 
04.12.19
21:44
(12) а какую последовательность физических операторов выберет движок СУБД зависит от настроек СУБД, версии СУБД, статистики и божьей воли.
Иногда даже в самых простых случаях выбираются очень странные штуки.
И при помощи бубна, магии и мата иногда удается получить нормальный план, а иногда нет
14 palsergeich
 
04.12.19
21:57
СУБД ничего не знает о том что какая та таблица является таблицей ссылочного типа.
Когда ты в запросе через точку от ссылки достанешь поле - синтаксический движок одинЭс заботливо втихаря бахает левое соединение.
Чем больше возможных типов у ссылки в метаданных тем больше соединений. Когда выбран тип любая ссылка в тексте запроса, который приходит на СУБД гирлянда этих левых соединений на добрый десяток страниц, а потом юзеры жалуются, что отборы через точку от регистратора работают по пол часа
15 palsergeich
 
04.12.19
21:59
Так все же, пока я еду домой, задай конкретный вопрос, постараюсь ответить.
16 OnNeOn
 
04.12.19
22:14
(15) РЕСПЕКТ!
Вопрос конкретный: Почему внутренее соединение должно работать дольше чем левое?
17 palsergeich
 
04.12.19
22:20
(16) кто сказал что должно?
В каких-то случаях работает быстрее, в каких то медленнее.
Как правило посмотрев на план можно дать этому логичное объяснение.
18 OnNeOn
 
04.12.19
22:25
(17) Ясно, т.е. кто говорит что левое работает быстрее тот не понимает как оно работает, правильно говорить, что чаще левое работает быстрее?ъ\
19 H A D G E H O G s
 
04.12.19
22:27
(18) Нет. Правильно говорить - "профайлер покажет, где кто говнокодил.".
20 palsergeich
 
04.12.19
22:29
(18) в общем случае рекомендуется использовать внутреннее.
Про своей практике в большинстве случаев результаты у него лучше, но не всегда.
21 palsergeich
 
04.12.19
22:31
А ещё лучше не соединение, а объединение с группировкой, на малых выборках итоговых данных разница может быть поразительной
22 GANR
 
05.12.19
00:02
(0) sql-ex.ru
23 Конструктор1С
 
05.12.19
08:11
(0) а зачем тебе знать, как работают низкоуровневые внутренности? Какой в этом практический смысл?
24 Sserj
 
05.12.19
08:30
(23) Любые значения имеют смысл.
Проблема не в скорости левого или полного соединения. Проблема в построении плана запроса и выбора индекса.
Допустим элементарный запрос
ВЫБРАТЬ ..
ИЗ Документ.Поступление КАК Поступление
   ВНУТРЕННЕЕ СОЕДИНЕНИЕ
   Справочник.Склады КАК Склады ПО Поступление.Склад = Склады.Ссылка
ГДЕ Поступление.Дата МЕЖДУ &НачДата И &КонДата

Логично предположить что SQLСервер сначала должен выбрать документы за период
а потом их соединить со складами. Но SQLсервер ничего не знает о том что в поле Поступление.Склад все значения должны соответствовать Склады.Ссылка. 1С при создании таблиц не делает никаких указаний по заполнению полей кроме того что они не NULL. Поэтому SQLСервер вполне может посмотреть - о в таблице складов всего 10 записей, давай я сначала отберу все документы у которых есть соответствие с таблицей складов а уже потом из этих выберу с нужным периодом.
А если указывается
ИЗ Документ.Поступление КАК Поступление
   ЛЕВОЕ СОЕДИНЕНИЕ
   Справочник.Склады КАК Склады ПО Поступление.Склад = Склады.Ссылка
То SQL всегда сначала наложит отборы на главную таблицу и уже потом поищет ему соответствие во второстепенной.
25 Sserj
 
05.12.19
08:32
+(24) Особенно это актуально если вдруг у Поступление.Склад установлен признак индексирования. Тогда SQLсервер практически однозначно решит при ВНУТРЕННЕЕ СОЕДИНЕНИЕ использовать этот индекс и сначала все документы связать со всеми складами.