Мне было интересно, есть ли какая-либо разница в том, как 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. Это мое личное мнение.
Ответ 4
Смотрите это
Предложение INNER JOIN ON vs WHERE
Ответ 5
Это дубликат этого SO-запроса: Явное vs неявное объединение SQL. Вообще я думаю, что неявная (где версия) плохая форма и не такая ясная, как явная (в версии). Я также думаю, что имплицитный амортизируется, но не 100% на него. План выполнения одинаковый для обоих.