Явные против неявных объединений SQL - PullRequest
364 голосов
/ 05 сентября 2008

Есть ли разница в эффективности в явном и неявном внутреннем соединении? Например:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

против

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;

Ответы [ 12 ]

122 голосов
/ 05 сентября 2008

По производительности они одинаковы (по крайней мере, в SQL Server).

PS: помните, что синтаксис IMPLICIT OUTER JOIN устарел с SQL Server 2005. (Синтаксис IMPLICIT INNER JOIN, используемый в вопросе, все еще поддерживается)

Устаревание синтаксиса JOIN «старого стиля»: только частичная вещь

120 голосов
/ 05 сентября 2008

Лично я предпочитаю синтаксис объединения, так как он проясняет, что таблицы объединяются и как они объединяются. Попробуйте сравнить большие запросы SQL, где вы выбираете из 8 разных таблиц, и у вас есть много фильтрации в где. Используя синтаксис объединения, вы разделяете части, в которых объединяются таблицы, на части, где вы фильтруете строки.

45 голосов
/ 25 апреля 2012

В MySQL 5.1.51 оба запроса имеют идентичные планы выполнения:

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1 имеет 166208 строк; table2 имеет около 1000 строк.

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

33 голосов
/ 25 ноября 2008

Второй синтаксис имеет нежелательную возможность перекрестного соединения: вы можете добавлять таблицы в часть FROM без соответствующего предложения WHERE. Это считается вредным.

14 голосов
/ 07 сентября 2008

В первом ответе, который вы дали, используется так называемый синтаксис объединения ANSI, другой действителен и будет работать в любой реляционной базе данных.

Я согласен с Grom, что вы должны использовать синтаксис ANSI соединения. По их словам, главная причина в ясности. Вместо того, чтобы иметь предложение where с большим количеством предикатов, некоторые из которых объединяют таблицы, а другие ограничивают строки, возвращаемые с помощью синтаксиса объединения ANSI, вы четко и ясно представляете, какие условия используются для объединения ваших таблиц, а какие - для ограничения результаты.

6 голосов
/ 05 сентября 2008

@ lomaxx: Просто чтобы прояснить, я почти уверен, что оба вышеуказанных синтаксиса поддерживаются SQL Serv 2005. Однако приведенный ниже синтаксис НЕ поддерживается

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

В частности, внешнее соединение (* =) не поддерживается.

4 голосов
/ 05 сентября 2008

С точки зрения производительности, они абсолютно одинаковы (по крайней мере, в SQL Server), но имейте в виду, что они не поддерживают этот синтаксис объединения, и он не поддерживается sql server2005 "из коробки".

Я думаю, вы думаете об устаревших операторах * = и = * против "внешнего соединения".

Я только что проверил два указанных формата, и они правильно работают в базе данных SQL Server 2008. В моем случае они дали одинаковые планы выполнения, но я не мог с уверенностью сказать, что это всегда будет правдой.

2 голосов
/ 05 сентября 2008

В некоторых базах данных (особенно в Oracle) порядок объединений может иметь огромное значение для производительности запросов (если имеется более двух таблиц). В одном приложении мы имели буквально разность в два порядка в некоторых случаях. Использование синтаксиса внутреннего соединения дает вам контроль над этим - если вы используете правильный синтаксис подсказок.

Вы не указали, какую базу данных вы используете, но вероятность подсказывает, что SQL Server или MySQL там, где нет никакой разницы.

1 голос
/ 30 ноября 2011

Производительность мудрая, это не должно иметь никакого значения. Явный синтаксис объединения кажется мне чище, поскольку он четко определяет отношения между таблицами в предложении from и не загромождает предложение where.

1 голос
/ 17 сентября 2008

Как заявил Ли Колдуэлл, оптимизатор запросов может создавать различные планы запросов на основе того, что функционально выглядит как один и тот же оператор SQL. Для дальнейшего прочтения рассмотрите следующие два сообщения в блоге: -

Одна публикация от команды оптимизатора Oracle

Еще одно сообщение из блога "Структурированные данные"

Надеюсь, вы найдете это интересным.

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