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

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

6 ответов

Решение

Любой запрос, включающий более одной таблицы, требует определенной формы связи, чтобы связать результаты из таблицы "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 JOIN вместо синтаксиса ANSI-92. Некоторые могут жаловаться на то, что синтаксис ANSI-92 более многословен, но именно это делает его явным. Чем более явным, тем легче понять и поддерживать.

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

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

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

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

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

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

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

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

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

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

Вы не можете использовать ГДЕ, чтобы объединить две таблицы. Что вы можете сделать, это написать:

SELECT * FROM A, B
WHERE ...

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

SELECT *
FROM A
CROSS JOIN B
WHERE ...

Вы бы написали это? Нет - потому что это совсем не то, что ты имеешь в виду. Вы не хотите перекрестное соединение, вы хотите ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Но когда вы пишете запятую, вы говорите CROSS JOIN, и это сбивает с толку.

На самом деле вам часто нужны "ГДЕ" и "ПРИСОЕДИНЯЙТЕСЬ".

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

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

Другие вопросы по тегам