Явный и неявный JOIN

Модераторы: kdv, CyberMax

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Явный и неявный JOIN

Сообщение Merlin » 19 сен 2006, 17:41

CyberMax писал(а):Есть такая вещь, как неявный джойн. Она существует как наследие SQL-89. Тем не менее, это не полезная, это вредная вещь.
В чём ейная экстраординарная вредность?

[Модератор: тема отделена от http://forum.ibase.ru/phpBB2/viewtopic.php?t=2564]

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 19 сен 2006, 18:18

Merlin писал(а):В чём ейная экстраординарная вредность?
В необходимости поддержки в движке сервера такой фичи :D

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 20 сен 2006, 01:44

Merlin писал(а):В чём ейная экстраординарная вредность?
В слове "неявный" :).

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 26 сен 2006, 16:46

2 Merlin. Цитирую нашу уже почти родную Хелен Борри:
Неявное соединение поддерживается в Firebird для совместимости с кодом существующих приложений. [...] Можно предположить, что в будущем стандарте этот синтаксис будет отсутствовать.
Кстати, WildSery был практически прав. Хотя, возможно, сейчас ситуация выглядит уже другим образом. Если это так, пусть разработчики поправят.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 26 сен 2006, 17:31

Хотя, возможно, сейчас ситуация выглядит уже другим образом. Если это так, пусть разработчики поправят.
искоренять неявный джойн никто не будет, в здравом уме.
и мне не представляется что он перестанет поддерживаться как минимум в ближайшие 10 лет.

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

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 26 сен 2006, 21:17

Знач так.

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

Во-вторых, даже в FB1 (а может и в 1.5, но ручаться не буду) ещё имеет место необходимость в некоторых запросах в явных джойнах для получения хорошего плана искусственно затаскивать условия фильтрации Where в ON, то есть в условия объединения, что с ортодоксальной точки зрения "явности" есть уродование эстетики. В то же время этот же запрос в неявном виде оптимизатор обслуживает на ура. Не говоря уже о более ранних версиях.

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

Эт всё, ессно, касается только Inner джойнов, ибо неявными могут быть только они.

В-четвёртых, ни один стандарт никогда не отменяет предыдущий, а дополняет или расширяет его.

Такшта, мнением по этому поводу моей старой подружки можно мне не тыкать ;) Хоть книжка ета (в оригинале, ессно) у меня лежит на полке с автографом, должен сказать, что это дааалеко не единственный пункт, где мы расходимся во мнениях. Ну и, ессно, там где мы таки в них расходимся, всегда прав я :-D

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 27 сен 2006, 07:52

Я так понимаю, Хелен просто решила запугать новичков. Для профилактики. А то начнут комбинировать явные джоины с неявными, порушат сервер...

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 27 сен 2006, 08:57

С Мерлином трудно не согласиться.:)
И не надо искоренять неявные джойны в моих исходниках за годы работы их скопилось мягко говоря изрядное кол-во, особенно в старом наследии... :oops: ежель их все в явные переписывать... :roll:

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 27 сен 2006, 11:40

В целом, соглашусь с Мерлином. Но есть пара сомнений.
Merlin писал(а):в смысле присобачивания к ним разных условий фильтрации - в нём всегда уже есть WHERE и можно не думая приляпывать очередной AND.
Не аргумент ваще. Если даже настолько лень, всегда есть вариант WHERE 1=1
Merlin писал(а):...мы просто обязаны писать её и её условия соединения последними, иначе парсер просто не сожрёт.
Тут не догнал. Можно пример, чего "парсер не сожрёт"?
Merlin писал(а):При этом не факт что оптимальная последовательность пересечений множеств будет соответствовать записи. И совсем не факт, что оптимизатор вообще будет ей следовать.
И наоборот, при неявном соединении, оптимизатор будет в точности выполнять всё что задумал автор, так что ли понимать сей аргумент?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 27 сен 2006, 14:27

WildSery писал(а):
Merlin писал(а):в смысле присобачивания к ним разных условий фильтрации - в нём всегда уже есть WHERE и можно не думая приляпывать очередной AND.
Не аргумент ваще. Если даже настолько лень, всегда есть вариант WHERE 1=1
select first 1 skip 100000 * from sebg_arc
where 1=1

Elapsed time= 0.34 sec

first 1 skip 100000 * from sebg_arc

Elapsed time= 0.26 sec

Ы? Оба запроса выполнены в монопольном доступе к серверу, первыми после подключения к базе. Для гашения эффекта файлового кеша оси - к двум разным инстансам, полученным в разное время рестором с одного оригинала. Эта таблица - трёхмиллионник, первые 100000 - данные с прошлого века, то есть лежат там одинаково.

Но аргумент действительно так себе. Потому как в моём построителе есть метод Filter.HaveActiveConds, можно текст запроса парсить и искать в нем незакомментаренное where... Но мне таки действительно лень, да и компам есть чем кроме этого заняться.
WildSery писал(а):
Merlin писал(а):...мы просто обязаны писать её и её условия соединения последними, иначе парсер просто не сожрёт.
Тут не догнал. Можно пример, чего "парсер не сожрёт"?
Реальные запросы, на которых спотыкался и искать лень и места до фига займут. Примитивный экзампл:

Код: Выделить всё

select T.*
 from T T1
  join T T2 on T2.ID=T1.ID and T2.ID=T3.ID
  join T T3 on T3.ID=T1.ID
в неявном все таблицы перечислены ДО наложения условий.
WildSery писал(а):
Merlin писал(а):При этом не факт что оптимальная последовательность пересечений множеств будет соответствовать записи. И совсем не факт, что оптимизатор вообще будет ей следовать.
И наоборот, при неявном соединении, оптимизатор будет в точности выполнять всё что задумал автор, так что ли понимать сей аргумент?
Нет, это надо понимать как то, что наглядность явного обманчива и на самом деле никаких преимуществ перед неявным не даёт.

Да, чуть не забыл. Никакого разного механизма обслуживания явных и неявных джойнов в сервере нет. Есть парсер, который понимает и то и другое и передаёт уже пожёваный результат дальше, один и тот же.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 27 сен 2006, 14:32

Dimitry Sibiryakov писал(а):Я так понимаю, Хелен просто решила запугать новичков. Для профилактики. А то начнут комбинировать явные джоины с неявными, порушат сервер...
Не исключаю :)

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 29 сен 2006, 05:14

kdv писал(а):кроме того, использование только неявных или наоборот, только явных джойнов граничит с ортодоксальностью, причем бессмысленой.
Начну издалека: все старое - более "дубовое" по сравнению с новым. Взять любую область - программы, техника, дома и т.д. - это правило работает. Но без этого никак - потому что это и есть эволюция.
Сначала придумали неявный джойн. Потом придумали явный джойн, более "утонченный". Таким образом, неявный джойн остался на предыдущей ступени эволюции. Если в новом стандарте появится какой-то новый тип джойна (например, явно-неявный :) ), то я буду в первых рядах адептов нового типа джойна :).
Таким образом, применив цитату kdv к вышесказанному, получим, что "Использование только черно-белых или цветных телевизоров граничит с ортодоксальностью..." или "Программирование только под Windows 3.11 или только под Windows 2000 граничит с ортодоксальностью...". Тем не менее, цветные телевизоры и Windows 2000 - это настоящее, а ч/б телевизоры и Win3.11 - это прошлое.

Как уже было сказано, все "предыдущее" - более простое. Ведь действительно, применение неявного джойна тупо до простоты - указываются две таблицы, а в where условие соединения. А в явном надо указывать тип соединения - внешний/внутренний, а также слово "JOIN"... Так вот, эта простота - достоинство, которое иногда перевешивает остальные недостатки. В качестве примера приведу военную технику - она должна быть очень проста, чтобы уменьшить вероятность выхода из строя и уменьшить затраты на ее изготовление. Идеальный пример - Автомат Калашникова.

Возражения же Merlin'а сводятся только к фразам наподобие "А вот паруснику топливо не надо!" и "Nokia 3310 можно пинать и ничего ей не будет!", тем не менее факт остается фактом - парусников нет, а Нокий 3310 все меньше и меньше...

P.S. Прошу прощения за философстования. Долго обдумывал ответ и, надеюсь, его смысл понятен.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 29 сен 2006, 09:56

есть заблуждение относительно "старый-новый". Да, неявный джойн был описан в более старой версии стандарта, но новая версия стандарта это не отмена предыдущего, и не сигнал что "все старое должно уйти на помойку".

Andrew Sagulin
Сообщения: 53
Зарегистрирован: 11 мар 2005, 15:44

Сообщение Andrew Sagulin » 29 сен 2006, 11:13

Я выскажусь осторожно: там, где применение явного и неявного join-а одинаково удобно, лучше, я так думаю, применять явный, чтобы отделить мух от котлет, т.е. условия соединения от условий фильтрации. И никакого фанатизма, в любом случае. :roll:
Кстати, мешать вместе явный и неявный join - это моветон и не имеет права на жизнь, или могут быть варианты?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 29 сен 2006, 11:16

2 Merlin:
Кроме случаев "парсер не сожрёт" (невозможно переделать в явный только при условии использования трёх условий по каждому из трёх алиасов), есть ещё какие-нибудь ситуации, когда явный join уступает неявному?

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 29 сен 2006, 11:17

Кстати, мешать вместе явный и неявный join - это моветон и не имеет права на жизнь, или могут быть варианты?
Это полный мастдай поскольку срывает серверу крышу. Я не могу припомнить точно, но багоглюки там были - мама не горюй.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 29 сен 2006, 22:52

WildSery писал(а):2 Merlin:
Кроме случаев "парсер не сожрёт" (невозможно переделать в явный только при условии использования трёх условий по каждому из трёх алиасов), есть ещё какие-нибудь ситуации, когда явный join уступает неявному?
Мне неизвестны. Кстати, прям сегодня на FB1.5.3 наступил на случай, когда в явном inner джойне опять получался совершенно разный план в зависимости от того, в where или в on размещено одно из условий. Переписывать на неявный и сверять было влом, непростой денёк выдался. Я не пытаюсь сказать что явный хуже или лучще, я пытаюсь донести что они равноправны. Есть нюансы, которые надо учитывать при пользовании тем и другим и всё. Вот если имеем цепочку inner соединений, на конце которой привешен left (а тут ясен перец весь запрос должен быть явным) то на 1.5.х частенько получается она, белая, круглая, полная, одним словом - жопа. Последовательность объединений не рулится секцией Plan и на тех же индексах запрос, который может выполняться за десятки мсек, идёт сотни :(

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 29 сен 2006, 22:58

CyberMax писал(а): Начну издалека: все старое - более "дубовое" по сравнению с новым.
Неверная посылка. Тут дело не в старом и новом. Можно сказать - да ну его нах, не пойду с сегодня вотку пить, а можно - не поёду я сегодня вотку пить, н уего нах. Вот и вся разница.

ЗЫ
Пардон за орфоргафию, я-то пошёл :) Отмечаем с опозданием на неделю мою днюху на работе :)

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 30 сен 2006, 08:37

2 Merlin. Так ведь код сервера постоянно улучшается. И теоретически появление "белых, круглых и полных" должно стремиться к нулю при подобных ситуациях...
К слову, медленные планы наблюдал и у себя на FB2 при одновременном использовании INNER JOIN и LEFT JOIN. Правилось сменой всех INNER на LEFT...

P.S. Ну и это... С Днем Рождения :D.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 02 окт 2006, 17:42

Merlin писал(а):Последовательность объединений не рулится секцией Plan и на тех же индексах запрос, который может выполняться за десятки мсек, идёт сотни :(
На глаз не припоминаю, чтобы не получилось добиться хорошего плана. Наверное, у тебя запросы посложнее? Или такие бяки строю отдельно в ХП, как вложенный.

Ответить