Плюсы/минусы MySql JOINS
Когда я выбираю данные из нескольких таблиц, я часто использовал JOINS, и недавно я начал использовать другой способ, но я не уверен в последствиях в конечном итоге.
Примеры:
SELECT * FROM table_1 LEFT JOIN table_2 ON (table_1.column = table_2.column)
Итак, это ваш основной LEFT JOIN через таблицы, но посмотрите на запрос ниже.
SELECT * FROM table_1,table_2 WHERE table_1.column = table_2.column
Лично, если бы я соединился, можно сказать, что 7 таблиц данных я бы предпочел сделать это через JOINS.
Но есть ли какие-либо плюсы и минусы в отношении двух методов?
Ответы
Ответ 1
Второй метод - это ярлык для INNER JOIN.
SELECT * FROM table_1 INNER JOIN table_2 ON table_1.column = table_2.column
Будет выбирать только записи, соответствующие условию в обеих таблицах (LEFT JOIN будет выбирать все записи из таблицы слева и сопоставлять записи из таблицы справа)
Цитата из http://dev.mysql.com/doc/refman/5.0/en/join.html
[...] мы рассматриваем каждую запятую в списке элементов table_reference как эквивалентное внутреннему соединению
и
INNER JOIN и (запятая) семантически эквивалентны при отсутствии условия соединения: оба производят декартово произведение между указанными таблицами (т.е. каждая строка в первой таблице соединяется с каждой строкой в вторая таблица).
Однако приоритет оператора запятой меньше, чем INNER JOIN, CROSS JOIN, LEFT JOIN и т.д. Если вы смешиваете запятую с другими типами соединений, когда есть условие соединения, может возникнуть ошибка формы Неизвестный столбец "col_name" в разделе "on". Информация о решении этой проблемы приведена ниже в этом разделе.
В общем, здесь упоминается немало вещей, которые должны заставлять вас не использовать запятые.
Ответ 2
Первый метод - это ANSI/ISO версия Join. Второй метод - это более старый формат (pre-89) для получения эквивалента Inner Join. Он делает это путем перекрестного соединения всех таблиц, которые вы перечисляете, а затем сужения декартова произведения в предложении Where, чтобы произвести эквивалент внутреннего соединения.
Я бы настоятельно рекомендовал против второго метода.
- Другим разработчикам труднее читать
- Это нарушает правило наименьшего удивления для других разработчиков, которые задаются вопросом, просто ли вы не знаете ничего лучше или если есть какая-то конкретная причина не использовать формат ANSI/ISO.
- Это вызовет у вас горе, когда вы начнете пытаться использовать этот формат с чем-то другим, кроме Inner Joins.
- Это затрудняет понимание вашего намерения, особенно в большом запросе со многими таблицами. Все ли эти таблицы должны быть внутренними соединениями? Вы пропустили что-то в предложении Where и создали крест? Вы намеревались сделать крест? И т.д.
Просто нет причин использовать второй формат, и на самом деле многие системы баз данных заканчивают поддержку этого формата.
Ответ 3
Синтаксис ANSI
Оба запроса - JOIN, и оба используют синтаксис ANSI, но один старше другого.
Объединение с использованием ключевого слова JOIN
означает, что используется синтаксис ANSI-92. Синтаксис ANSI-89 - это когда вы разделяете таблицы запятыми в предложении FROM
, а критерии, которые их объединяют, находятся в предложении WHERE
. При сравнении INNER JOINs нет разницы в производительности - это:
SELECT *
FROM table_1 t1, table_2 t2
WHERE t1.column = t2.column
... создаст тот же план запроса, что и:
SELECT *
FROM TABLE_1 t1
JOIN TABLE_2 t2 ON t2.column = t1.column
Яблоки в апельсины
Другое отличие состоит в том, что два запроса не идентичны: LEFT [OUTER] JOIN будет вызывать все строки из TABLE_1
, а ссылки на TABLE_2
на выходе будут NULL, если нет соответствия, основанного на критериях JOIN (указано в предложении ON
). Второй пример - INNER JOIN, который будет только создавать строки, имеющие соответствующие записи в TABLE_2
. Здесь ссылка на визуальное представление JOINs, чтобы усилить разницу...
Плюсы/минусы
Основная причина использования синтаксиса ANSI-92 заключается в том, что ANSI-89 не имеет поддержки OUTER JOIN (LEFT, RIGHT, FULL). Синтаксис ANSI-92 был специально введен для устранения этого недостатка, поскольку поставщики применяли собственный собственный пользовательский синтаксис. Oracle использовал (+)
; SQL Server использовал звездочку на стороне равных в критериях соединения (IE: t1.column =* t2.column
).
Следующая причина использования синтаксиса ANSI-92 заключается в том, что он более явный, более читаемый, в то же время разделяя то, что используется для объединения таблиц и фактической фильтрации.
Ответ 4
Я лично считаю, что явный синтаксис соединения (A JOIN B
, A LEFT JOIN B
) является предпочтительным. И то, и другое, потому что он более явный в отношении того, что вы делаете, и потому что, если вы используете неявный синтаксис соединения для внутренних соединений, вам все равно придется использовать явный синтаксис для внешних соединений, и поэтому ваше форматирование SQL будет непоследовательным.
Ответ 5
Я согласен с тем, что Мчль и Томас писали в своих ответах. Я особо подчеркиваю, что вам следует избегать второго примера (где вы указываете соединение через предложение WHERE
) и переходите к более явной форме JOIN ... ON
.
Я спорю, потому что явная версия (LEFT JOIN ... ON ... = ...
) имеет еще одно важное преимущество: у вас спецификация соединения четко разделена (в предложении JOIN ... ON
) из фактических условий фильтрации (в предложении WHERE
), что делает код SQL более понятным и понятным.