我遇到了这个问题
recently,在网上找不到任何关于它的讨论.
下面的查询
DECLARE @S VARCHAR(1) = ''; WITH T AS (SELECT name + @S AS name2,* FROM master..spt_values) SELECT * FROM T T1 INNER JOIN T T2 ON T1.name2 = T2.name2;
始终获得嵌套循环计划
尝试使用INNER HASH JOIN或INNER MERGE JOIN提示强制执行此问题会产生以下错误.
Query processor could not produce a query plan because of the hints
defined in this query. Resubmit the query without specifying any hints
and without using SET FORCEPLAN.
我发现了一种允许使用散列或合并连接的解决方法 – 将变量包装在聚合中.产生的计划成本显着降低(19.2025 vs 0.261987)
DECLARE @S2 VARCHAR(1) = ''; WITH T AS (SELECT name + (SELECT MAX(@S2)) AS name2,* FROM spt_values) SELECT * FROM T T1 INNER JOIN T T2 ON T1.name2 = T2.name2;
这种行为的原因是什么?并且有没有比我找到的更好的解决方法? (这可能不需要额外的执行计划分支)
解决方法
我已经在sql 2012实例上尝试了您的查询,跟踪标志4199似乎解决了这个问题.启用它后,我得到一个合并连接,总成本为0.24,没有额外的分支.
此问题的特定知识库文章是Performance issues occur when the join predicate in your query has outer reference columns in SQL Server 2005 or in SQL Server 2008
为了进一步获得资格,TF 4199支持所有优化器修复.有关更多信息,请参见this link.一次启用所有内容可能会产生奇怪的副作用,因此如果您能找到特定的修复程序,最好自己启用修复程序.
您可以使用OPTION(QUERYTRACEON 4199)在每个查询的基础上启用跟踪标志.