|
|
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Ну вообщем по совету Мимопроходящего, помещаю свой вопрос в эту тему.. Допустим есть у меня 2 таблицы А и B соединенные по какому - то полю (пусть индекс создан) A.id = B.id_A. И хочу я запрос составить, как будет корректней написать select ... from A left join B on A.id = B.id_A или select ... from A,B where A.id = B.id_A Я всегда думала что правильно - 1-й в-т - ну типа для каждой записи A ищется соотв. по условию запись из В, и таким образом формируется результат, а второй - не правильно - там вначале формируются все варианты А на В, а затем из этой громадины перемноженной отбираются те записи, для которых выполняется условие where A.id = B.id_A. Но что-то последнее время довольно часто натыкаюсь на второй вариант, может на самом деле он выполняется аналогично первому,или тут есть какая-то заморочка на тип БД в которой запрос пишется, или на наличие/отсутствие индекса... Я послушала бы чье-то мнение по этому поводу ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2004, 20:17:53 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Запросы неэквивалентны. У тебя там LEFT JOIN . А это совсем не то же самое, что where A.id = B.id_A Отличие OUTER от INNER JOIN 'а знаешь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2004, 20:22:44 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
отличие то я понимаю, where A.id=B.id_A , будет по рез. исполнения эквивалентно inner, но тут как бы 2 подвопроса 1. Так же он будет выполняться (where экв. inner join ?) (я думала что inner выполняется так - для кажд. записи A находим все соотв. по условию записи в B, а те для которых не нашли убираем) 2.Сущ. ли конструкция where экв. left join по рез. віполнения (возможно какие-то условные обозначения типа "*=" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2004, 20:36:44 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Виталяотличие то я понимаю, where A.id=B.id_A , будет по рез. исполнения эквивалентно inner, но тут как бы 2 подвопроса 1. Так же он будет выполняться (where экв. inner join ?)В простейшем случае - да. Виталя2.Сущ. ли конструкция where экв. left join по рез. выполнения (возможно какие-то условные обозначения типа "*="Это у Oracle есть. Приблизительным смысловым эквивалентом (для ограниченный случаев) будет конструкция: Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2004, 20:48:31 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Меня очень смущают слова "в простейшем случае" и "приблизительно". Ведь говорить о том что процесс 1. Вначале "перемножим" A(10 000 записей) на B(10 000 записей) (получим 100 000 000 записей), а затем выберем по условию того же inner нужные (5 000). и процесс 2. "Пройдя" по A(10000) прикрепляем записи из B по условию, и выкидывая из A, те записи для которых не нашли. эквивалентны даже приблизительно - неверно - во втором случае временно хранить 100 000 000 записей не нужно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2004, 20:59:25 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Виталя 1. Вначале "перемножим" A(10 000 записей) на B(10 000 записей) (получим 100 000 000 записей), а затем выберем по условию того же inner нужные (5 000). Такого никогда не произойдет. Для понятности процесса можно (и нужно) представить INNER JOIN как вложенные циклы, где необходимые условия проверяются на каждом уровне вложенности. Добавлю также, что JOIN выполняется в процессе фетча, т.е. новые записи будет вычитываться из таблиц и объединяться по мере надобности. JOIN (без сортировки) никогда не приводит к формированию какого-либо промежуточного буфера. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.08.2004, 22:40:37 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Замечательно - что при использовании JOIN "перемножения" не произойдет, но я вообще-то спрашивала произойдет ли оно при использовании связки по where ? или where будет обрабатываться так же как и inner join ? меня интересует сам процесс формирования результата, а не результат... что более верно where или join ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 12:06:37 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Простой вариант для нахождения ответа на ваш вопрос: посмотрите статистику выполнения запросов, если разницы нет, то... значит нет ёё. А корректнее, некоректнее... Всё равно перенос логики работы с версии на версии даже одной СУБД не происходит идеально гладко, а уж тем более с одного сервера на другой. Короче - если нет разницы - зачем платить больше? Ну... может быть если только выбран какой-либо определенный стиль написания SQL clause в команде ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 12:43:15 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
ВиталяЗамечательно - что при использовании JOIN "перемножения" не произойдет, но я вообще-то спрашивала произойдет ли оно при использовании связки по where ? или where будет обрабатываться так же как и inner join ? меня интересует сам процесс формирования результата, а не результат... что более верно where или join ? INNER JOIN полностью эквивалентен неявному джойну (твой WHERE) как по процессу, так и по результату. LEFT JOIN - вещь немного другая и отличается результатом, хотя процесс и там точно такой же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 13:59:55 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
dimitr INNER JOIN полностью эквивалентен неявному джойну (твой WHERE) как по процессу, так и по результату. Насчет результата согласен, а по процессу вопросик: В запросе Код: plaintext 1. 2. 3. А если "перевернуть" запрос Код: plaintext 1. 2. 3. В неявном join-e оптимизатор сам выберет, какую таблицу как читать. Как он это сделает? Уж не исходя ли из порядка перечисления таблиц во from? Ну и как это при большем количестве таблиц выглядеть будет? И еще вопрос. Я частенько при помощи join-ов неявно планами рулю. Вот интересно, в двойке в этом отношении изменения будут? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 14:37:52 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
авторВ неявном join-e оптимизатор сам выберет, какую таблицу как читать. Как он это сделает? Уж не исходя ли из порядка перечисления таблиц во from? оптимизатору пофиг, в каком порядке ты таблицы укажешь. он постарается начать объединение с самой маленькой таблицы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 14:48:42 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
Откуда такие сведения? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 14:55:18 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
авторЯ частенько при помощи join-ов неявно планами рулю. Вот интересно, в двойке в этом отношении изменения будут? ты лучше расскажи, как тебе удалось добиться влиять на оптимизатор? я вот сколько чего не меняю местами - он всё равно по своему делает. вообщем-то так и должно быть - на то он и оптимизатор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 15:00:30 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
ЛентяйНасчет результата согласен, а по процессу вопросик: В запросе Код: plaintext 1. 2. 3. А если "перевернуть" запрос Код: plaintext 1. 2. 3. Чушь. Оба раза план будет одинаковым. То, что ты говоришь, будет при LEFT JOIN, что, впрочем, вполне понятно. ЛентяйВ неявном join-e оптимизатор сам выберет, какую таблицу как читать. Как он это сделает? Уж не исходя ли из порядка перечисления таблиц во from? Никак нет. Исходя из стоимости выполнения запроса, определяемой статистикой, размером таблиц и используемыми индексами. ЛентяйНу и как это при большем количестве таблиц выглядеть будет? Точно так же - порядок выберет оптимизатор. ЛентяйЯ частенько при помощи join-ов неявно планами рулю. Вот интересно, в двойке в этом отношении изменения будут? Гонишь ведь ;-) Рулить планами можно только путем LEFT vs INNER. Но тут можно огрести на ORDER BY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 15:06:19 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
dimitr Чушь. Оба раза план будет одинаковым. То, что ты говоришь, будет при LEFT JOIN, что, впрочем, вполне понятно. Вот планы для запросов для FB 1.5 4481 под XP : Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. dimitr ЛентяйВ неявном join-e оптимизатор сам выберет, какую таблицу как читать. Как он это сделает? Уж не исходя ли из порядка перечисления таблиц во from? Никак нет. Исходя из стоимости выполнения запроса, определяемой статистикой, размером таблиц и используемыми индексами. А вот для неявных join-ов Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. Может такие результаты потому что таблички тестовые и в них данных мало? ЛентяйЯ частенько при помощи join-ов неявно планами рулю. Вот интересно, в двойке в этом отношении изменения будут? Гонишь ведь ;-) Рулить планами можно только путем LEFT vs INNER. Но тут можно огрести на ORDER BY. По поводу явных join я с left всегда планами рулил, а в какой-то момент показалось что это и с inner работает... Кроме того помогает SP первой поставить, а к ней таблички join-ом ... А по поводу order by это я в курсе... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 15:46:14 |
|
||
|
Соединение таблиц JOIN или WHERE ?
|
|||
|---|---|---|---|
|
#18+
ЛентяйМожет такие результаты потому что таблички тестовые и в них данных мало? Теоретически такое возможно (если кардинальность таблиц и селективность индексов идентична), но на практике не встречал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.08.2004, 16:04:49 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=32663771&tid=1578029]: |
0ms |
get settings: |
4ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
190ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
| others: | 187ms |
| total: | 465ms |

| 0 / 0 |
