我有一张有几十行的桌子。简化设置如下
CREATE TABLE #data ([Id] int, [Status] int);
INSERT INTO #data
VALUES (100, 1), (101, 2), (102, 3), (103, 2);
Run Code Online (Sandbox Code Playgroud)
我有一个查询将这个表连接到一组表值构造的行(由变量和常量组成),比如
DECLARE @id1 int = 101, @id2 int = 105;
SELECT
COALESCE(p.[Code], 'X') AS [Code],
COALESCE(d.[Status], 0) AS [Status]
FROM (VALUES
(@id1, 'A'),
(@id2, 'B')
) p([Id], [Code])
FULL JOIN #data d ON d.[Id] = p.[Id];
Run Code Online (Sandbox Code Playgroud)
查询执行计划显示优化器的决定是使用FULL LOOP JOIN策略,这似乎是合适的,因为两个输入都有很少的行。但是,我注意到(并且不能同意)的一件事是正在假脱机的 TVC 行(请参阅红色框中的执行计划区域)。
为什么优化器在这里引入spool,这样做的原因是什么?除了线轴没有什么复杂的。看起来是没有必要的。在这种情况下如何摆脱它,可能的方法是什么?
上述计划获得于
Microsoft SQL Server 2014 (SP2-CU11) (KB4077063) - 12.0.5579.0 (X64)
这个问题是关于VALUES从这里和这里开始的构造的优化器行为探索的延续。我想问一下VALUES和APPLY这次。
使用CROSS APPLY别名作为需要在查询的各个部分中引用的表达式是常见的模式。例如:
CREATE TABLE #data (N int);
INSERT INTO #data VALUES (5), (4), (3), (2), (1);
SELECT d.N, c.[Square]
FROM #data d
CROSS APPLY (VALUES (d.N * d.N)) c([Square])
WHERE c.[Square] BETWEEN 1 AND 10
ORDER BY c.[Square];
Run Code Online (Sandbox Code Playgroud)
我自己总是CROSS APPLY在这种情况下使用,但有时我会遇到包裹在 inline-TVF 和OUTER APPLY-ed 中的此类表达式。因此,出于好奇,我换CROSS到OUTER的exampling查询
SELECT d.N, c.[Square]
FROM #data d
OUTER APPLY (VALUES (d.N * d.N)) c([Square])
WHERE c.[Square] …Run Code Online (Sandbox Code Playgroud)