Sql 为什么在具有多个联接的WHERE子句中,子查询的性能要比普通值好?

Sql 为什么在具有多个联接的WHERE子句中,子查询的性能要比普通值好?,sql,sql-server,join,scalar-subquery,Sql,Sql Server,Join,Scalar Subquery,请转到以下查询: SELECT * FROM FactALSAppSnapshot AS LB LEFT OUTER JOIN MLALSInfoStage AS LA ON LB.ProcessDate = LA.ProcessDate AND LB.ALSAppID = LA.ALSNumber LEFT OUTER JOIN MLMonthlyIncomeStage

请转到以下查询:

SELECT *
FROM FactALSAppSnapshot AS LB 
     LEFT OUTER JOIN MLALSInfoStage AS LA ON LB.ProcessDate = LA.ProcessDate AND 
                                                   LB.ALSAppID = LA.ALSNumber
     LEFT OUTER JOIN MLMonthlyIncomeStage AS LC ON LB.ProcessDate = LC.ProcessDate AND
                                                        LB.ALSAppID = LC.ALSNumber
     LEFT OUTER JOIN DimBranchCategory AS LI on LB.ALSAppBranchKey = LI.Branch
WHERE LB.ProcessDate=(SELECT TOP 1 LatestProcessDateKey
                      FROM DimDate)
请注意,WHERE条件是一个标量子查询。运行时间为0:54,产生367853条记录

但是,如果我将WHERE子句切换为以下内容:

WHERE LB.ProcessDate=20161116
这以某种方式导致查询运行时跳到57:33,仍然会产生367853条记录。幕后发生了什么会导致运行时出现如此巨大的跳跃?我希望子查询版本需要更长的时间,而不是文字整数值

列表上别名为LI last join的表似乎是唯一一个未在其键上建立索引的表,如果我将该表作为join删除并使用整数值而不是子查询,则该表似乎允许查询执行更接近第一个查询的查询


SQL Server 11

问题的真正答案在于查询的执行计划。您可以在SSMS中看到实际计划

如果没有这个计划,剩下的就是猜测。但是,根据我的经验,连接的处理方式发生了变化。根据我的经验,当查询切换到嵌套循环联接时,查询速度会大大降低。这是优化器一时兴起的,优化器(当存在常量时)认为这是运行查询的最佳方式


我不知道为什么会这样。也许FactalAppSnapshotProcessDate、ALSAppID和ALSAppBranchKey上的索引会加速两个版本的查询。

您的问题的真正答案在于查询的执行计划。您可以在SSMS中看到实际计划

如果没有这个计划,剩下的就是猜测。但是,根据我的经验,连接的处理方式发生了变化。根据我的经验,当查询切换到嵌套循环联接时,查询速度会大大降低。这是优化器一时兴起的,优化器(当存在常量时)认为这是运行查询的最佳方式


我不知道为什么会这样。也许FactalAppSnapshotProcessDate、ALSAppID和ALSAppBranchKey上的索引会加速这两个版本的查询。

这很奇怪。从DimDate返回中选择前1位的LatestProcessDateKey是什么?LB.ProcessDate的类型是什么,是否编制了索引?你说什么?这是一个积极使用的生产数据库吗?如果是这样的话,那可能是因为您在等待一个锁。如果您使用Declare@d date=convertdate,20161116。。。其中LB.ProcessDate=@d@Schwern这个小的子查询返回我今天插入的值,它是截至2016年11月16日的整数。ProcessDate是一个YYYYMMDD日期表示形式,它是一个int。我必须在早上解释MSG。从技术上讲,它被用作生产服务器,只是在有限的容量下使用。ProcessDate是组合键的一部分,所以我假设它是索引的。这很奇怪。从DimDate返回中选择前1位的LatestProcessDateKey是什么?LB.ProcessDate的类型是什么,是否编制了索引?你说什么?这是一个积极使用的生产数据库吗?如果是这样的话,那可能是因为您在等待一个锁。如果您使用Declare@d date=convertdate,20161116。。。其中LB.ProcessDate=@d@Schwern这个小的子查询返回我今天插入的值,它是截至2016年11月16日的整数。ProcessDate是一个YYYYMMDD日期表示形式,它是一个int。我必须在早上解释MSG。从技术上讲,它被用作生产服务器,只是在有限的容量下使用。ProcessDate是组合键的一部分,因此我假设它已被索引。