В запросах MySQL зачем использовать join вместо где? - PullRequest
101 голосов
/ 11 февраля 2010

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

Ответы [ 6 ]

150 голосов
/ 11 февраля 2010

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

8 голосов
/ 11 февраля 2010

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

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

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

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

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

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

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

6 голосов
/ 11 февраля 2010

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

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

5 голосов
/ 11 февраля 2010

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

3 голосов
/ 11 февраля 2010

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

SELECT * FROM A, B
WHERE ...

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

SELECT *
FROM A
CROSS JOIN B
WHERE ...

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

0 голосов
/ 03 июня 2017

На самом деле вам часто нужны «ГДЕ» и «ПРИСОЕДИНЯЙТЕСЬ». «JOIN» используется для извлечения данных из двух таблиц - на основе значений общего столбца. Если вы хотите дополнительно отфильтровать этот результат, используйте предложение WHERE.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...