Задать вопрос
kit_de
@kit_de
Моя... Твоя... Привет!

Что лучше JOIN или использование нескольких таблиц в запросе?

Короч, игрался тут с маськой (MySQL) и заметил такую штуку:
Запрос
SELECT product.maker, pc.price
FROM product, PC
WHERE product.model = pc.model

Возвращает те же данные что и
SELECT maker, price FROM Product JOIN PC
ON PC.model = Product.model

Подскажите, в чем разница между этими двумя вариантами выполнения команды? Есть ли там какие-то особенности в производительности?
  • Вопрос задан
  • 1332 просмотра
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
Melkij
@Melkij
PostgreSQL DBA
mysql> explain select test6.i from test6, test9 where test6.i=test9.i;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
|  1 | SIMPLE      | test6 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL                                               |
|  1 | SIMPLE      | test9 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |    25.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
2 rows in set, 1 warning (0,00 sec)

mysql> show warnings;
+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                                                                 |
+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Note  | 1003 | /* select#1 */ select `test`.`test6`.`i` AS `i` from `test`.`test6` join `test`.`test9` where (`test`.`test9`.`i` = `test`.`test6`.`i`) |
+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)

mysql> explain select test6.i from test6 join test9 on test6.i=test9.i;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                              |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
|  1 | SIMPLE      | test6 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | NULL                                               |
|  1 | SIMPLE      | test9 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |    25.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------------------------------------------+
2 rows in set, 1 warning (0,00 sec)

mysql> show warnings;
+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                                                                 |
+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Note  | 1003 | /* select#1 */ select `test`.`test6`.`i` AS `i` from `test`.`test6` join `test`.`test9` where (`test`.`test9`.`i` = `test`.`test6`.`i`) |
+-------+------+-----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)

Как можно заметить, оба стиля переписаны в одно и то же представление.

Имеет смысл использовать join on по соображениям читаемости человеком, т.к. такой join сразу говорит, по каким полям связаны таблицы, а where органично остаётся для фильтрации.
Плюс, в случае как у вас со связью по паре одноимённых полей можно написать
SELECT maker, price FROM Product JOIN PC USING(model)

Что эквивалентно PC.model = Product.model, но короче и позволяет в дальнейшем ссылаться просто на model - парсер уже знает, что значение поля будет идентично и не будет теряться в догадках, хотели вы получить model из PC или из Product
Ответ написан
Комментировать
lxfr
@lxfr
На youtube есть хорошие видео в том числе на русском которые наглядно показывают разницу между запросами из всех таблиц и join'ами. Разница в быстродействии там колоссальная и там наглядно показывается почему.
Ответ написан
dimonchik2013
@dimonchik2013
non progredi est regredi
лучше JOIN

вообще есть доклад про внутренности MySQL, где показано, что JOIN очень шустро работает с процессором (чтобы держать в памяти только итоговое, а не все исходные таблицы), так что JOIN совсем не такой, каким кажется/рисуется
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы