В MySQL-запросах зачем использовать соединение вместо того, где?

Кажется, что для объединения двух или более таблиц мы можем либо использовать join, либо где. Каковы преимущества одного над другим?

Ответ 1

Любой запрос, включающий более одной таблицы, требует определенной формы связи, чтобы связать результаты из таблицы "A" с таблицей "B". Традиционные средства (ANSI-89) для этого:

  1. Перечислите таблицы, включенные в список через запятую, в предложении FROM
  2. Напишите связь между таблицами в предложении WHERE

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id
    

Здесь запрос переписан с использованием синтаксиса ANSI-92 JOIN:

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

С точки зрения производительности:


Там, где это поддерживается (Oracle 9i+, PostgreSQL 7. 2+, MySQL 3. 23+, SQL Server 2000+), нет никакой выгоды в производительности при использовании любого синтаксиса по сравнению с другим. Оптимизатор видит их как один и тот же запрос. Но более сложные запросы могут выиграть от использования синтаксиса ANSI-92:

  • Возможность контролировать порядок JOIN - порядок сканирования таблиц
  • Возможность применения критериев фильтра к таблице до присоединения

С точки зрения технического обслуживания:


Существует множество причин использовать синтаксис ANSI-92 JOIN поверх ANSI-89:

  • Более читабелен, так как критерии JOIN отделены от предложения WHERE
  • Меньше шансов пропустить критерии ПРИСОЕДИНЕНИЯ
  • Согласованная поддержка синтаксиса для типов JOIN, отличных от INNER, что упрощает использование запросов в других базах данных
  • Предложение WHERE служит только для фильтрации декартовых произведений объединяемых таблиц.

С точки зрения дизайна:


Синтаксис ANSI-92 JOIN - это шаблон, а не анти-шаблон:

  • Цель запроса более очевидна; столбцы, используемые приложением, понятны
  • Он следует правилу модульности о строгой типизации, когда это возможно. Явное почти всегда лучше.

Заключение


Если не считать знакомства и/или комфорта, я не вижу никакой пользы в том, чтобы продолжать использовать предложение ANSI-89 WHERE вместо синтаксиса ANSI-92 JOIN. Некоторые могут жаловаться, что синтаксис ANSI-92 более многословен, но именно это делает его явным. Чем более явным, тем легче понять и поддерживать.

Ответ 2

Это проблемы с использованием синтаксиса where (другим мудрым, называемым неявным соединением):

Во-первых, слишком легко получить случайные кросс-соединения, потому что условия соединения не подходят рядом с именами таблиц. Если у вас есть шесть таблиц, которые объединены вместе, легко пропустить один в предложении where. Вы увидите, что это исправлено слишком часто, используя отдельное ключевое слово. Это огромный успех для базы данных. Вы не можете получить случайное кросс-соединение, используя синтаксис явного соединения, поскольку он не сможет проверить синтаксис.

Правовые и левые соединения проблематичны (на сервере SQl вы не можете получить правильные результаты) в старом синтаксисе в некоторых базах данных. Кроме того, они устарели в SQL Server, я знаю.

Если вы собираетесь использовать кросс-соединение, это не ясно из старого синтаксиса. Это ясно, используя текущий стандарт ANSII.

Гораздо сложнее, если разработчик точно видит, какие поля являются частью соединения или даже какие таблицы объединяются в каком порядке с использованием неявного синтаксиса. Это означает, что для пересмотра запросов может потребоваться больше времени. Я знал очень мало людей, которые, когда они нашли время, чтобы чувствовать себя комфортно с явным синтаксисом соединения, когда-либо возвращались к старому пути.

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

Честно говоря, вы бы использовали любой другой код, который был заменен лучшим методом 18 лет назад?

Ответ 3

Большинство людей склонны находить синтаксис JOIN немного более четким в отношении того, к чему присоединяется. Кроме того, он имеет преимущество в качестве стандартного.

Лично я "вырос" на WHEREs, но чем больше я использую синтаксис JOIN, тем больше я начинаю видеть, как это более понятно.

Ответ 4

Явные объединения передают намерение, оставляя предложение where для фильтрации. Он чище и стандартен, и вы можете делать такие вещи, как левый внешний или правый внешний, который сложнее сделать только с тем, где.

Ответ 5

Вы не можете использовать WHERE для объединения двух таблиц. Но вы можете написать:

SELECT * FROM A, B
WHERE ...

Здесь запятая эквивалентна записи:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

Не могли бы вы написать это? Нет, потому что это не то, что вы имеете в виду. Вы не хотите перекрестного соединения, вы хотите INNER JOIN. Но когда вы пишете запятую, вы говорите CROSS JOIN и это сбивает с толку.

Ответ 6

На самом деле вам часто нужны как "WHERE", так и "JOIN".

"JOIN" используется для извлечения данных из двух таблиц - на основе значений общего столбца. Если вы хотите еще больше фильтровать этот результат, используйте предложение WHERE.

Например, "LEFT JOIN" извлекает ВСЕ строки из левой таблицы, а также соответствующие строки из правой таблицы. Но это не фильтрует записи по любому конкретному значению или по другим столбцам, которые не являются частью JOIN. Таким образом, если вы хотите дополнительно фильтровать этот результат, укажите дополнительные фильтры в предложении WHERE.