Зачем в запросах MySQL использовать join вместо where?


109

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


2
В зависимости от вашего использования он может иметь те же результаты, но с JOIN вы можете создавать другие виды ассоциаций.
zneak

Отвечает ли это на ваш вопрос? Предложение
INNER

Ответы:


161

Любой запрос, включающий более одной таблицы, требует некоторой формы ассоциации для связывания результатов из таблицы «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
  • Поддержка согласованного синтаксиса для типов JOIN, отличных от INNER, что упрощает использование запросов в других базах данных.
  • Предложение WHERE служит только для фильтрации декартова произведения объединенных таблиц.

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


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

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

Вывод


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


14
«... Любой запрос, включающий более одной таблицы, требует некоторой формы ассоциации, чтобы связать результаты из таблицы 'A' с таблицей 'B' ... В противном случае вы получите декартово произведение, и вы, вероятно, не захотите этого (эти картезианцы производят ЛЮБИМЫЕ продукты)
Скотт Смит,

8

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

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


1
@nawfal Я понимаю - я был воспитан на синтаксисе старого стиля, но как только я привык к новому, преимущества стали очевидны, например, сложнее выполнить перекрестное соединение по ошибке, более явное, легче увидеть, что такое соединение, а что фильтр и т.д ... Меня зацепило.
Basic

8

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

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

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

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

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

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

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


6

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


3

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

SELECT * FROM A, B
WHERE ...

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

SELECT *
FROM A
CROSS JOIN B
WHERE ...

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


0

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.