Плюсы/минусы 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 более понятным и понятным.