JOIN的ON子句中引用的表的顺序是否重要?

Eve*_*ien 35 mysql sql sql-server oracle

在JOIN的ON子句中为哪些方式排序标准是否重要?

select a.Name, b.Status from a
inner join b
on a.StatusID = b.ID
Run Code Online (Sandbox Code Playgroud)

select a.Name, b.Status from a
inner join b
on b.ID = a.StatusID
Run Code Online (Sandbox Code Playgroud)

对性能有影响吗?如果我有多个标准怎么办?

一个订单比另一个订单更易维护吗?

Qua*_*noi 33

JOIN可以通过在FROM子句中按正确的顺序放置表来强制执行命令:

  1. MySQL有一个特殊的子句STRAIGHT_JOIN,它使命令很重要.

    这将使用索引b.id:

    SELECT  a.Name, b.Status
    FROM    a
    STRAIGHT_JOIN
            b
    ON      b.ID = a.StatusID
    
    Run Code Online (Sandbox Code Playgroud)

    这将使用索引a.StatusID:

    SELECT  a.Name, b.Status
    FROM    b
    STRAIGHT_JOIN
            a
    ON      b.ID = a.StatusID
    
    Run Code Online (Sandbox Code Playgroud)
  2. Oracle有一个ORDERED强制执行JOIN订单的特殊提示:

    这将使用索引b.id或构建哈希表b:

    SELECT  /*+ ORDERED */
            *
    FROM    a
    JOIN    b
    ON      b.ID = a.StatusID
    
    Run Code Online (Sandbox Code Playgroud)

    这将使用索引a.StatusID或构建哈希表a:

    SELECT  /*+ ORDERED */
            *
    FROM    b
    JOIN    a
    ON      b.ID = a.StatusID
    
    Run Code Online (Sandbox Code Playgroud)
  3. SQL Server有一个提示被称为FORCE ORDER执行相同的操作:

    这将使用索引b.id或构建哈希表b:

    SELECT  *
    FROM    a
    JOIN    b
    ON      b.ID = a.StatusID
    OPTION (FORCE ORDER)
    
    Run Code Online (Sandbox Code Playgroud)

    这将使用索引a.StatusID或构建哈希表a:

    SELECT  *
    FROM    b
    JOIN    a
    ON      b.ID = a.StatusID
    OPTION (FORCE ORDER)
    
    Run Code Online (Sandbox Code Playgroud)
  4. PostgreSQL的家伙,对不起.你的TODO清单说:

    优化器提示(不需要)

    优化程序提示用于解决优化程序中的问题.我们宁愿报告和修复问题.

至于比较中的顺序,任何RDBMSAFAIK都无关紧要.

虽然我个人总是试图估计将搜索哪一列,并将此列放在左侧(因为它看起来像一个lvalue).

有关详细信息,请参阅此答案.

  • 很棒的答案!+1 (3认同)
  • 关于“PostgreSQL 伙计们,抱歉” - 官方 TODO http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want 中的“优化器提示”。 (2认同)
  • 我有点惊讶。OP 询问了“ON”子句的顺序,并展示了一个示例,其中他没有反转表,而只反转了“ON”子句,但此答案仅处理反转表顺序的情况。还是最后的评论_"至于比较中的顺序...."_是指吗? (2认同)

Óla*_*age 9

不,不是的.

我做的(为了便于阅读)是你的第二个例子.


Dav*_*vid 5

不可以.数据库应该根据整个标准确定最佳执行计划,而不是通过按顺序查看每个项目来创建它.您可以通过请求两个查询的执行计划来确认这一点,您将看到它们是相同的(您会发现即使是最大不同的查询,只要它们最终指定相同的逻辑,通常会被编译到相同的执行计划中).