在内部连接之前使用子查询更有效吗?

时间:2013-07-25 23:03:12

标签: mysql performance select inner-join

我正在学习MYSQL,并且有一些我一直在想的事情。

让我们采用这个简单的场景:一个假设的网站,用于参加在线课程,包括4个表:学生,教师,课程和注册(学生注册的每门课程一个条目)

您可以找到数据库生成代码on github

虽然提供的数据库很小,但为了保持与我需要的帮助相关,我们假设这是一个足够大的数据库,效率将是一个真正的问题 - 让我们来看看说成千上万的学生,老师等。



就我对MYSQL的理解而言,如果我们想要一个由查尔斯达尔文教授的学生表,可能会有一个问题:

方法1

SELECT Students.name FROM Teachers
INNER JOIN Courses ON Teachers.id = Courses.teacher_id
INNER JOIN Registrations ON Courses.id = Registrations.course_id
INNER JOIN Students ON Registrations.student_id = Students.id
WHERE Teachers.name = "Charles Darwin"

确实会返回我们想要的东西。

+----------------+
| name           |
+----------------+
| John Doe       |
| Jamie Heineman |
| Claire Doe     |
+----------------+


所以这是我的问题:

凭借我(非常)有限的MYSQL知识,在我看来,在这里我们JOIN - 将元素放在教师桌上,这可能非常大,而我们最终只是在一位老师之后,我们在查询的最后过滤掉。

我的直觉'说首先为我们需要的老师获取一行会更有效率,然后将剩余的东西加入其中:

方法2

SELECT Students.name FROM (SELECT Teachers.id FROM Teachers WHERE Teachers.name = 
"Charles Darwin") as Teacher
INNER JOIN Courses ON Teacher.id = Courses.teacher_id
INNER JOIN Registrations ON Courses.id = Registrations.course_id
INNER JOIN Students ON Registrations.student_id = Students.id

但事实确实如此吗?假设有数千名教师和学生,这比第一次查询更有效吗?可能MYSQL足够智能,可以解析方法1查询,使其运行更有效。


此外,如果有人可以提出更有效的查询,我也会非常有兴趣听到它。

注意:我之前已经阅读过使用EXPLAIN来确定查询效率的方法,但我不能很好地理解MYSQL以便能够破译结果。这里的任何见解也将非常受欢迎。

1 个答案:

答案 0 :(得分:1)

  

我的'直觉'说首先得到的效率要高得多   我们需要的老师一行,然后加入其余的   相反的东西:

通过使用谓词Teachers.name = "Charles Darwin",您可以在方法1中为教师获取单行。查询优化器应确定在加入其他表之前使用此谓词限制Teacher集更有效。

如果您不信任优化器或想要减少它所做的工作,您甚至可以使用SELECT STRAIGHT_JOIN ...STRAIGHT_JOIN代替INNER_JOIN强制执行表读取顺序以确保MySQL按照您在查询中指定的顺序读取表。

您的第二个查询会得到相同的答案,但可能效率较低,因为会为您的教师子查询创建一个临时表。

EXPLAIN documentation是解释EXPLAIN输出的良好来源。