Mar*_*ith 16 performance sql-server optimization query-performance
我最近遇到了这个问题,在网上找不到任何讨论。
下面的查询
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;
Run Code Online (Sandbox Code Playgroud)
总是得到一个嵌套循环计划

尝试使用INNER HASH JOIN或INNER MERGE JOIN提示强制问题会产生以下错误。
由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用 SET FORCEPLAN 的情况下重新提交查询。
我找到了一种允许使用散列或合并连接的解决方法 - 将变量包装在聚合中。生成的计划成本显着降低(19.2025 与 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;
Run Code Online (Sandbox Code Playgroud)

这种行为的原因是什么?有没有比我找到的更好的解决方法?(这可能不需要额外的执行计划分支)
Tom*_*m V 13
我已经在 SQL 2012 实例上尝试过您的查询,并且跟踪标志 4199 似乎解决了这个问题。启用它后,我获得了一个合并连接,总成本为 0.24,并且没有任何额外的分支。
此问题的特定知识库文章是当查询中的联接谓词在 SQL Server 2005 或 SQL Server 2008 中具有外部引用列时会出现性能问题

为了进一步符合条件,TF 4199 启用了所有优化器修复。有关更多信息,请参阅此链接。一次启用所有内容可能会产生奇怪的副作用,因此如果您能找到特定的修复程序,最好单独启用该修复程序。
您可以使用OPTION (QUERYTRACEON 4199);在每个查询的基础上启用跟踪标志;
| 归档时间: |
|
| 查看次数: |
787 次 |
| 最近记录: |