SQL - 多个INNERJOIN的最快查询

时间:2016-10-13 07:35:24

标签: mysql sql inner-join multiple-columns

哪个查询更快 - (或者没关系)?

SELECT *
FROM students as s
INNER JOIN hallprefs as hp
    ON s.studentid = hp.studentid
INNER JOIN halls as h
    ON hp.hallid = h.hallid

SELECT *
FROM students as s
INNER JOIN hallprefs as hp
INNER JOIN halls as h
    ON hp.hallid = h.hallid
    AND s.studentid = hp.studentid

当然,最初的问题是更多的表格。

1 个答案:

答案 0 :(得分:0)

这些评论都提到了相同的观点,它在性能方面不重要,第二个查询不符合ANSI标准。 MySQL允许它的原因是因为

  

在MySQL中,JOIN,CROSS JOIN和INNER JOIN是语法等价物(它们可以互相替换)。在标准SQL中,它们不等效。 INNER JOIN与ON子句一起使用,否则使用CROSS JOIN。

摘自online documentation

所以第二个查询的ANSI等价物是:

SELECT *
FROM students as s
CROSS JOIN hallprefs as hp
INNER JOIN halls as h
    ON hp.hallid = h.hallid
    AND s.studentid = hp.studentid;

同样,这个重写应该对性能没有影响,SQL是一种声明性语言,所以你告诉引擎你想要它做什么,而不是你想要它做什么,所以因为这两个查询的意图是完全一样,人们希望优化者能够达到两者的相同计划。这当然并非总是如此,尽管我非常肯定对于像这样的简单情况,它将适用于所有DBMS。

对于SQL来说,答案最快/更有效等几乎总是,这取决于。它取决于您的架构,索引,数据类型,数据分布,数据库供应商/版本。因此,虽然可以给出一般指导原则,但真正的答案是测试。

至于哪种更好的做法,我认为这实际上取决于你的意图,前者的问题是你可能决定只想在halls上离开,所以要调整你的查询:

SELECT *
FROM students as s
CROSS JOIN hallprefs as hp
LEFT JOIN halls as h
    ON hp.hallid = h.hallid
    AND s.studentid = hp.studentid;

您介绍了笛卡尔积,而第一个查询的相同更改并未执行此操作。

SELECT *
FROM students as s
INNER JOIN hallprefs as hp
    ON s.studentid = hp.studentid
LEFT JOIN halls as h
    ON hp.hallid = h.hallid;

现在,意图可能是拥有笛卡尔积,在这种情况下,交叉连接解决方​​案更适合这种情况。再一次,这取决于你的里程可能会有所不同。