SQL - 多个 INNERJOIN 的最快查询

SQL - The fastest query for multiple INNERJOIN

哪个查询更快 -(或者无关紧要)?

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

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

评论都提到了相同的观点,即在性能方面应该无关紧要,并且第二个查询不符合 ANSI。 MySQL允许的原因是因为

In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents (they can replace each other). In standard SQL, they are not equivalent. INNER JOIN is used with an ON clause, CROSS JOIN is used otherwise.

摘自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 时,答案是 fastest/more 高效等几乎总是,这取决于。这将取决于您的架构、索引、数据类型、数据分布、数据库 vendor/version。因此,虽然可以给出一般准则,但真正的答案是测试。

至于哪种做法更好,我认为这实际上取决于您的意图,前者的问题在于您可能决定只想在 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;

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