sql-server – 为什么引用连接谓词中的变量强制嵌套循环?

前端之家收集整理的这篇文章主要介绍了sql-server – 为什么引用连接谓词中的变量强制嵌套循环?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我遇到了这个问题 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)在每个查询的基础上启用跟踪标志.

猜你在找的MsSQL相关文章