SQL JOIN: существует ли разница между USING, ON или WHERE?

Мне было интересно, есть ли какая-либо разница в том, как SQL выполняет эти утверждения:

SELECT * FROM a,b WHERE a.ID = b.ID

SELECT * FROM a JOIN b ON a.ID = b.ID

SELECT * FROM a JOIN b USING(ID)

Есть ли разница в производительности? Или алгоритмическая разница?

Или это просто синтаксический сахар?

Ответ 1

Нет никакой разницы в производительности.

Однако первый стиль - ANSI-89, и в некоторых магазинах ваши ноги сломаются. Включая мой. Второй стиль - ANSI-92 и намного понятнее.

Примеры:

Каков JOIN, который является фильтром?

FROM T1,T2,T3....
WHERE T1.ID = T2.ID AND
     T1.foo = 'bar' AND T2.fish = 42 AND
     T1.ID = T3.ID

FROM T1 
   INNER JOIN T2 ON T1.ID = T2.ID
   INNER JOIN T3 ON T1.ID = T3.ID
WHERE
   T1.foo = 'bar' AND T2.fish = 42

Если у вас есть ВЗАИМОДЕЙШИЕ СОЕДИНЕНИЯ (=*, *=), тогда второй стиль будет работать как рекламируемый. Первый, скорее всего, не будет и также устарел в SQL Server 2005 +

Стиль ANSI-92 более сложный для bollix. В более старом стиле вы можете легко получить декартово произведение (перекрестное соединение), если вы пропустите условие. Вы получите синтаксическую ошибку с ANSI-92.

Изменить: несколько уточнений

  • Причиной не использовать "join the where" (неявный) является изнурительный результат с внешними объединениями.
  • Если вы используете явные вложенные JOINs + неявные INNER JOINs, вы все равно получите изворотливые результаты + у вас есть несогласованность в использовании

Это не просто синтаксис: он имеет семантически правильный запрос

Изменить, декабрь 2011

Порядок обработки логических запросов SQL Server - FROM, ON, JOIN, WHERE...

Итак, если вы смешиваете "неявные внутренние соединения WHERE" и "явные внешние соединения FROM", вы, скорее всего, не получите ожидаемых результатов, потому что запрос неоднозначен...

Ответ 2

Разница - читаемость и ремонтопригодность. SELECT * FROM a JOIN b ON a.ID = b.ID передает ваше точное намерение, все в одном месте.

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

Ответ 3

Я презираю, когда вы принудительно соединяете, используя WHERE. Мне просто не нравится, грязный хак. Правильное соединение ANSI - использовать ON:

SELECT 
    p.Product,
    o.Order
FROM 
    Product p
INNER JOIN
    Order o
ON
    o.OrderID = p.OrderID

Предпочтительно использовать ON при присоединении и WHERE для фильтрации результатов. Помните, что ГДЕ - одна из последних вещей, которые вы будете использовать, помимо группировки и порядка, где вы хотите отфильтровать результаты. Поэтому вы не должны присоединяться к своим таблицам с помощью WHERE, так как его трудно прочитать.

SELECT 
    p.Product,
    o.Order
FROM 
    Product p
INNER JOIN
    Order o
ON
    o.OrderID = p.OrderID
WHERE
    o.Category = 'IT'

В конце концов, вы (разработчик), возможно, не будете в будущем, поэтому читаемость и ремонтопригодность помогут раздуть душу, которая должна взять ваш код:).

Когда я вижу, что разработчики используют WHERE для объединения своих таблиц, это обычно указывает на то, что они не знают достаточно T-SQL. Это мое личное мнение.

Ответ 5

Это дубликат этого SO-запроса: Явное vs неявное объединение SQL. Вообще я думаю, что неявная (где версия) плохая форма и не такая ясная, как явная (в версии). Я также думаю, что имплицитный амортизируется, но не 100% на него. План выполнения одинаковый для обоих.