2015-05-24 5 views
0

У меня есть два различных запросов, которые возвращают те же данные:запросов: Сгруппированные РЕГИСТРИРУЙТЕСЬ против инлайн РЕГИСТРИРУЙТЕСЬ

+---------+-------------------------------+----------+ 
| title | body       | username | 
+---------+-------------------------------+----------+ 
| Welcome | You got a cool forum here  | john  | 
| Welcome | Great topics.     | boyd  | 
| Welcome | Nice to have you as members | cris  | 
| Looking | I have the time and knowlegde | boyd  | 
| Looking | I'm fully qualified for this | joe  | 
+---------+-------------------------------+----------+ 

Запрос I:

SELECT posts.title,comments.body,users.username 
FROM posts 
    LEFT JOIN (
     users INNER JOIN comments ON users.id = comments.user_id 
    ) ON posts.id = comments.post_id 

Запрос II:

SELECT posts.title,comments.body,users.username 
FROM posts 
    LEFT JOIN comments ON posts.id = comments.post_id 
    INNER JOIN users ON users.id = comments.user_id 

И это мои столы:

USERS 
+----+----------+ 
| id | username | 
+----+----------+ 
| 1 | john  | 
| 2 | boyd  | 
| 3 | ella  | 
| 4 | cris  | 
| 5 | joe  | 
| 6 | esses | 
| 18 | test2 | 
+----+----------+ 
      POSTS 
+----+-----------------------+ 
| id | title     | 
+----+-----------------------+ 
| 1 | Welcome    | 
| 2 | Looking for moderator | 
+----+-----------------------+ 

         COMMENTS 
+---------+---------+------------------------------------------+ 
| post_id | user_id | body          | 
+---------+---------+------------------------------------------+ 
|  1 |  1 | You got a cool forum here    | 
|  1 |  2 | Great topics.       | 
|  1 |  4 | Nice to have you as members    | 
|  2 |  2 | I have the time and knowlegde to do this | 
|  2 |  5 | I'm fully qualified for this job   | 
+---------+---------+------------------------------------------+ 

Мой вопрос: Какая разница между этими двумя запросами?

EDIT: Это является EXPLAIN EXTENDED результаты:

Query I:

- EXPLAIN EXTENDED

+----+-------------+----------+--------+---------------+---------+---------+----------------------+------+----------+-------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref     | rows | filtered | Extra  | 
+----+-------------+----------+--------+---------------+---------+---------+----------------------+------+----------+-------------+ 
| 1 | SIMPLE  | posts | ALL | NULL   | NULL | NULL | NULL     | 2 | 100.00 | NULL  | 
| 1 | SIMPLE  | comments | ALL | NULL   | NULL | NULL | NULL     | 5 | 100.00 | Using where | 
| 1 | SIMPLE  | users | eq_ref | PRIMARY  | PRIMARY | 4  | app.comments.user_id | 1 | 100.00 | NULL  | 
+----+-------------+----------+--------+---------------+---------+---------+----------------------+------+----------+-------------+ 

- ВЫСТАВКАХ ПРЕДУПРЕЖДЕНИЯ

+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Level | Code | Message                                                                             | 
+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Note | 1003 | /* select#1 */ select `app`.`posts`.`title` AS `title`,`app`.`comments`.`body` AS `body`,`app`.`users`.`username` AS `username` from `app`.`posts` left join (`app`.`users` join `app`.`comments`) on(((`app`.`posts`.`id` = `app`.`comments`.`post_id`) and (`app`.`users`.`id` = `app`.`comments`.`user_id`))) where 1 | 
+-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 

Запрос II:

- EXPLAIN EXTENDED

+----+-------------+----------+--------+---------------+---------+---------+----------------------+------+----------+----------------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref     | rows | filtered | Extra            | 
+----+-------------+----------+--------+---------------+---------+---------+----------------------+------+----------+----------------------------------------------------+ 
| 1 | SIMPLE  | comments | ALL | NULL   | NULL | NULL | NULL     | 5 | 100.00 | Using where          | 
| 1 | SIMPLE  | users | eq_ref | PRIMARY  | PRIMARY | 4  | app.comments.user_id | 1 | 100.00 | NULL            | 
| 1 | SIMPLE  | posts | ALL | PRIMARY  | NULL | NULL | NULL     | 2 | 100.00 | Using where; Using join buffer (Block Nested Loop) | 
+----+-------------+----------+--------+---------------+---------+---------+----------------------+------+----------+----------------------------------------------------+ 

- ВЫСТАВКИ ПРЕДОСТОРОЖНОСТЬ

+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Level | Code | Message                                                                          | 
+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Note | 1003 | /* select#1 */ select `app`.`posts`.`title` AS `title`,`app`.`comments`.`body` AS `body`,`app`.`users`.`username` AS `username` from `app`.`posts` join `app`.`comments` join `app`.`users` where ((`app`.`posts`.`id` = `app`.`comments`.`post_id`) and (`app`.`users`.`id` = `app`.`comments`.`user_id`)) | 
+-------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
+0

Я не думаю, что есть какая-то разница. – Barmar

+0

Запуск EXPLAIN EXTENDED ...; затем SHOW WARNINGS; по обоим запросам – Strawberry

+0

@ Клубника, @ Barmar. Я просто добавил объяснение расширенных результатов. Похоже, что первый запрос выполняет 1 дополнительный запрос. – boyd

ответ

0

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

+0

С точки зрения производительности, какой лучший запрос? – boyd

+0

это зависит от размера вашей таблицы. вы должны предсказать размер таблицы и на основании этого написать свой запрос – Mahmoud

0

Я думаю, что я прав в том, что запрос 2 функционально идентичен этому:

select p.title 
, c.body 
, u.username 
from posts p 
join comments c 
on p.id = c.post_id 
join users u 
    on u.id = c.user_id 

В то время как запрос 1 идентичен этому

select p.title 
, c.body 
, u.username 
from posts p 
join comments c 
on p.id = c.post_id 
left 
join users u 
on u.id = c.user_id 
where 1 
+0

Итак, существует только синтаксическая разница? – boyd

+0

№ Если я не ошибаюсь (и, может быть, есть), здесь есть логическая разница. Но вам было бы легко продемонстрировать с помощью своего набора данных – Strawberry

1

Join обрабатываются логически слева направо если вы не перепишете его с помощью круглых скобок.

Q1: posts LEFT (users INNER comments) 

posts остается присоединиться к результату (users INNER comments), что приводит все строки из posts нулей, где условие соединения не вычисляется TRUE

Q2: posts LEFT comments INNER users 

Теперь posts оставляется присоединился к comments первым , а столбцы из comments, которые не могут быть соединены, - NULLED. Затем этот результат соединяется с users с использованием внутреннего соединения. Но из-за NULL в comments.user_id строки, которые были добавлены из-за внешнего соединения, снова удаляются. На самом деле это то же самое, что и внутреннее соединение всех трех таблиц.

+0

. Разница между этими запросами не отличается от синтаксических? – boyd

+0

@boyd: Конечно, есть другой набор результатов. Но только ** вы ** знаете, какой из них правильный :-) – dnoeth

Смежные вопросы