我有两个不同的查询返回相同的数据:
+---------+-------------------------------+----------+
| 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 |
+---------+---------+------------------------------------------+
我的问题是:这两个查询之间真正的区别是什么?
编辑:这是EXPLAIN EXTENDED结果:
查询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 :(得分:1)
从左到右逻辑处理连接,除非您使用括号覆盖它。
Q1: posts LEFT (users INNER comments)
posts
与(users INNER comments)
的结果保持联接,这导致posts
的所有行都为NULL,其中连接条件未评估为TRUE
Q2: posts LEFT comments INNER users
现在posts
首先加入comments
,而comments
中无法加入的列为NULL。然后使用内部联接将此结果连接到users
。但由于comments.user_id
中的NULL,因外部连接而添加的行将再次被删除。实际上,这与连接所有三个表的内部相同。
答案 1 :(得分:0)
这两个查询之间没有概念上的区别,但为了提高性能,最好先通过加入更大的表来尽快缩小时态结果表,然后只选择所需的字段而不是全部。
答案 2 :(得分: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