SQL JOIN: есть ли разница между USING, ON или WHERE? - PullRequest
38 голосов
/ 13 апреля 2011

Мне было интересно, есть ли разница в том, как 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)

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

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

Ответы [ 5 ]

47 голосов
/ 13 апреля 2011

Различий в производительности нет.

Однако первый стиль - 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

Если у вас есть OUTER JOINs(=*, *=), тогда второй стиль будет работать так, как объявлено.Первый, скорее всего, не будет и также не рекомендуется в SQL Server 2005 +

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

Редактировать: Еще несколько уточнений

  • Причиной отказа от использования "join the where" (неявного) являются хитрые результаты с внешними объединениями.
  • Если вы используетеявные ВНЕШНИЕ СОЕДИНЕНИЯ + неявные ВНУТРЕННИЕ СОЕДИНЕНИЯ вы все равно получите хитрые результаты + у вас есть несогласованность в использовании

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

Edit, Dec 2011

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

Так что, если вы смешаете «неявные внутренние объединения» и «явные FROM внешние объединения», вы, скорее всего, не получите ожидаемых результатов, потому что запрос неоднозначный ...

4 голосов
/ 13 апреля 2011

Разница заключается в удобочитаемости и ремонтопригодности.SELECT * FROM a JOIN b ON a.ID = b.ID передает ваше точное намерение, все в одном и том же месте.

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

2 голосов
/ 13 апреля 2011

Я презираю, когда вы форсируете соединение, используя 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. Это мое личное мнение.

0 голосов
/ 13 апреля 2011

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

0 голосов
/ 13 апреля 2011
...