Sql JOIN命令会影响性能吗?

46 sql sql-server

当我遇到这个查询时,我只是整理了一些sql:

SELECT 
        jm.IMEI ,
        jm.MaxSpeedKM ,
        jm.MaxAccel ,
        jm.MaxDeccel ,
        jm.JourneyMaxLeft ,
        jm.JourneyMaxRight ,
        jm.DistanceKM ,
        jm.IdleTimeSeconds ,
        jm.WebUserJourneyId ,
        jm.lifetime_odo_metres ,
        jm.[Descriptor]
FROM    dbo.Reporting_WebUsers AS wu WITH (NOLOCK)
        INNER JOIN dbo.Reporting_JourneyMaster90 AS jm WITH (NOLOCK) ON wu.WebUsersId = jm.WebUsersId
        INNER JOIN dbo.Reporting_Journeys AS j WITH (NOLOCK) ON jm.WebUserJourneyId = j.WebUserJourneyId
WHERE   ( wu.isActive = 1 )
        AND ( j.JourneyDuration > 2 )
        AND ( j.JourneyDuration < 1000 )
        AND ( j.JourneyDistance > 0 )
Run Code Online (Sandbox Code Playgroud)

我的问题是它是否会使连接的顺序与我将要完成的上述查询的性能差异

FROM dbo.Reporting_JourneyMaster90 AS jm
Run Code Online (Sandbox Code Playgroud)

然后将其他2个表加入到那个表中

小智 42

SQL2008R2服务器中的连接顺序无疑会影响查询性能,尤其是在存在大量表连接的查询中,其中where子句应用于多个表.

虽然在优化中更改了连接顺序,但优化程序不会尝试所有可能的连接顺序.当它找到它认为可行的解决方案时它停止,因为优化的行为使用了宝贵的资源.

我们已经看到像狗一样执行的查询(1分钟+执行时间)仅通过改变连接表达式的顺序就可以达到次级性能.但请注意,这些是具有12到20个连接的查询,以及几个表中的子句.

诀窍是设置您的订单以帮助查询优化器找出有意义的东西.您可以使用强制订单,但这可能过于严格.尝试确保您的连接顺序从表中开始,这些表将通过where子句最大程度地减少数据.

  • @TomTom甚至Grant Fritchey的基于成本的优化器书也讨论了"优化器放弃"复杂查询的特定情况.他甚至可以使用Microsoft的演示数据库来演示它. (6认同)
  • 这可能只是一个参数嗅探问题,对查询的任何更改都会改进. (3认同)
  • 我已经使用SQL服务器超过10年了,并且第一次开始看到JOIN顺序会影响性能,就像在这个答案中所述.令人困惑的是,在认为优化器最了解的情况下,我偶然发现了这一点,同时寻找看到同样行为的其他人.是的,我的统计数据都是最新的. (2认同)
  • 这应该是正确的答案。FWIW:在我更改连接顺序之前,我复杂的大型 Oracle 查询从未完成。 (2认同)

Mik*_* M. 32

不,在优化期间按顺序更改JOIN.

唯一需要注意的是Option FORCE ORDER,它会按照你指定的确切顺序强制连接.

  • 我刚刚有一个使用MySQL的例子,它确实很重要,因为我正在订购从另一个表加入的Date。切换顺序使执行时间减少了20%。然后,添加分页,将执行时间减少了80%。所以我想这取决于。 (2认同)

小智 8

我有一个明显的内连接影响性能的例子.它是两个表之间的简单连接.一个有5000多万条记录,另一条有2000条.如果我从较小的表中选择并加入较大的表,则需要5分钟以上.

如果我从较大的表中选择并加入较小的表,则需要2分30秒.

这是SQL Server 2012.

对我来说,这是违反直觉的,因为我使用最大的数据集进行初始查询.

  • 如果您可以显示两种方案的执行计划,它会增强您的答案 (14认同)

Yar*_*lav 7

JOIN 顺序无关紧要,查询引擎将根据索引和其他内容的统计信息重新组织订单.

测试时请执行以下操作:

  • 选择显示实际执行计划并运行第一个查询
  • 更改JOIN顺序,现在再次运行查询
  • 比较执行计划

它们应该是相同的,因为查询引擎将根据其他因素重新组织它们.

正如在其他asnwer上评论的那样,你可以使用OPTION (FORCE ORDER)你想要的顺序,但也许它不是最有效的.

作为一般的经验法则,JOIN顺序应该是最上面的记录表,大多数记录最后,因为一些DBMS引擎的顺序可以产生差异,以及FORCE ORDER命令是否用于帮助限制结果.

  • 这个答案不太正确。我刚刚按照你的建议做了,查询运行时间下降了 25%。此外,为了确保这不是侥幸,我使用相同的逻辑对查询中的另一个 CTE 进行了更改,并将运行时间增加了 60%。 (2认同)

Den*_*rdy 6

通常不会。我不是100%逐字地应用到Sql-Server,但是在Postgres中,查询计划者保留按自己认为合适的方式对内部联接进行重新排序的权利。例外是,当您达到阈值时,调查更改其订单的成本太高。