Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql连接顺序是否影响性能?_Sql_Sql Server - Fatal编程技术网

Sql连接顺序是否影响性能?

Sql连接顺序是否影响性能?,sql,sql-server,Sql,Sql Server,我正在整理一些sql时遇到了以下查询: 选择 jm.IMEI, jm.MaxSpeedKM, jm.MaxAccel, jm.MaxDeccel, jm.journeymaxlight, jm.JourneyMaxRight, jm.distance公里, jm.idletimesconds, jm.WebUserJourneyId, jm.O.O.米, jm.[描述符] 来自dbo.Reporting_webuser作为wu WITH(NOLOCK) 将dbo.Reporting_Journe

我正在整理一些sql时遇到了以下查询:

选择
jm.IMEI,
jm.MaxSpeedKM,
jm.MaxAccel,
jm.MaxDeccel,
jm.journeymaxlight,
jm.JourneyMaxRight,
jm.distance公里,
jm.idletimesconds,
jm.WebUserJourneyId,
jm.O.O.米,
jm.[描述符]
来自dbo.Reporting_webuser作为wu WITH(NOLOCK)
将dbo.Reporting_JourneyMaster90作为jm与wu.WebUsersId=jm.WebUsersId上的(NOLOCK)进行内部连接
在jm.WebUserJourneyId=j.WebUserJourneyId上使用(NOLOCK)将dbo.u行程报告为j的内部联接
其中(wu.isActive=1)
和(j.行程持续时间>2)
和(j.行程持续时间<1000)
和(j.行程距离>0)
我的问题是,对于上面的查询,它是否会对连接的顺序产生任何性能差异

FROM dbo.Reporting_JourneyMaster90 AS jm

然后将其他两个表加入到该表中

通常不会。我不是百分之百地认为这会逐字应用于Sql Server,但在Postgres中,查询规划器保留对内部联接进行重新排序的权利。例外情况是,当您达到一个阈值,超过该阈值时,调查更改其顺序的成本太高。

否,在优化过程中,按顺序连接会发生更改


唯一需要注意的是,该选项将强制按照指定的顺序进行连接。

连接顺序不重要,查询引擎将根据索引和其他内容的统计信息重新组织连接顺序

对于测试,请执行以下操作:

  • 选择“显示实际执行计划”并运行第一个查询
  • 更改
    JOIN
    顺序,然后再次运行查询
  • 比较执行计划
它们应该相同,因为查询引擎将根据其他因素重新组织它们

正如在其他asnwer上所评论的,您可以使用
选项(强制订单)
来准确地使用您想要的订单,但可能这不是最有效的订单


一般的经验法则是,连接顺序应该是记录最少的表在顶部,大多数记录在最后,因为某些DBMS引擎的顺序可能会产生影响,如果使用强制顺序命令来帮助限制结果,则连接顺序也会产生影响。

错误。SQL Server 2005这肯定很重要,因为您从from子句开始就限制数据集。如果从2000条记录开始,而不是从200万条记录开始,查询速度会更快。

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

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

我们已经看到,通过改变连接表达式的顺序,执行起来像狗一样(1分钟+执行时间)的查询性能下降到了亚秒级。但是,请注意,这些查询在几个表上有12到20个联接和where子句


诀窍是设置您的顺序,以帮助查询优化者找出什么是有意义的。可以使用强制顺序,但这可能过于严格。尝试确保联接顺序从表开始,其中通过where子句减少数据最多

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

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

这是SQL Server 2012的特点


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

尝试运行这两个数据集并查看执行计划。他们有什么不同吗?我没料到会这样。我从来没有听说过它会影响性能。如果这样一个简单的查询速度很慢,我会假设您需要查看索引。它并不慢-只是看起来很奇怪,您会从一个表中选择所有列,但没有将其作为主表中的列,但这让我开始考虑性能,因为这需要可扩展,因为它将处理大量数据。我与SQL server合作超过10年,第一次看到连接顺序对性能的影响,如回答中所述。我感到困惑,因为我认为优化器知道得最好,所以在搜索其他看到相同行为的人时,我偶然发现了这一点。是的,我的统计数据都是最新的。这也可能是一个参数嗅探问题,对查询的任何更改都会改善情况。@TomTom甚至Grant Fritchey的基于成本的优化器书都谈到了在复杂查询中“优化器放弃”的特定场景。他甚至能够用微软的demo DB演示它。这应该是正确的答案。FWIW:在我更改联接顺序之前,我复杂的大型Oracle查询从未完成过。如果您能显示两个场景的执行计划,这将增强您的回答。也许where子句将大型表限制在一个很小的集合中,而它不能减少较小的表?我刚刚有一个使用MySQL的示例,它确实很重要,因为我是在另一张桌子上加入的日期订购的。切换顺序将执行时间减少了20%。然后,通过添加分页,它将执行时间减少了80%。所以我想这要视情况而定。这个答案不太正确。我完全按照你的建议做了,查询运行时下降了25%。此外,为了确保这不是偶然,我在查询中使用相同的逻辑对另一个CTE进行了更改,使运行时间增加了60%。