SELECT u.Id, mj.*
FROM dbo.Users_cx AS u --ColumnStore
JOIN dbo.MultiStatementTVF_Join(0) AS mj
ON mj.UserId = u.Id
WHERE u.LastAccessDate >= '2016-12-01';
SELECT u.Id, mj.*
FROM dbo.Users AS u --RowStore
JOIN dbo.MultiStatementTVF_Join(0) AS mj
ON mj.UserId = u.Id
WHERE u.LastAccessDate >= '2016-12-01';
这些查询各自连接到不同的表。一个 ColumnStore,一个不是。他们都获得了交错执行计划。
交错执行什么时候起作用?
目前,它仅适用于 MSTVF,其中关联是在函数之外完成的。
这里有几个例子:
此函数没有内部关联,这意味着没有WHERE基于表列和传入变量的子句。
CREATE OR ALTER FUNCTION dbo.MultiStatementTVF_Join
(
@h BIGINT
)
RETURNS @Out TABLE
(
UserId INT,
BadgeCount BIGINT
)
AS
BEGIN
INSERT INTO @Out ( UserId, BadgeCount )
SELECT b.UserId, COUNT_BIG(*) AS BadgeCount
FROM dbo.Badges AS b
GROUP BY b.UserId
HAVING COUNT_BIG(*) > @h;
RETURN;
END;
GO
这个函数是相反的,在UserId带有传入变量的列上有一个谓词。
CREATE OR ALTER FUNCTION dbo.MultiStatementTVF_CrossApply
(
@h BIGINT,
@id INT
)
RETURNS @Out TABLE
(
UserId INT,
BadgeCount BIGINT
)
AS
BEGIN
INSERT INTO @Out ( UserId, BadgeCount )
SELECT b.UserId, COUNT_BIG(*) AS BadgeCount
FROM dbo.Badges AS b
WHERE b.UserId = @id
GROUP BY b.UserId
HAVING COUNT_BIG(*) > @h;
RETURN;
END;
GO
SELECT u.Id, mj.*
FROM dbo.Users AS u --RowStore
CROSS APPLY dbo.MultiStatementTVF_Join(0) AS mj
WHERE mj.UserId = u.Id
AND u.LastAccessDate >= '2016-12-01';
SELECT TOP 1 u.Id, mj.*
FROM dbo.Users AS u --RowStore
CROSS APPLY dbo.MultiStatementTVF_CrossApply(2147483647, u.Id) AS mj
WHERE u.LastAccessDate >= '2016-12-01'
ORDER BY u.Id;
魔鬼在表变量中
交错执行旨在纠正多语句表值函数中误估的基数。
在 SQL Server 的早期版本中,这些函数总是会产生相当低的估计值:
不用说,这在连接到其他表时可能会导致很多问题。
虽然从表变量中选择数据本身并不会抑制并行性,但低行估计通常会有助于降低查询成本,而并行性不会被考虑在内。
使用交错执行时,基数估计会暂停,MSTVF 的子树会被执行,然后使用更准确的基数估计恢复优化。
我如何知道我的 MSTVF 是否收到交错执行。
与 Adaptive Join 一样,Interleaved Execution 在查询计划中注明。与 Adaptive Join 不同,它没有在估计的计划中注明,至少在撰写本文时是这样。
具有交错执行的 MSTVF 的计划形状与其中具有 MSTVF 的典型计划略有不同。
您将在计划顶部看到表值函数运算符,以及 TVF 运算符通常位于图形计划中的表变量扫描。
将鼠标悬停在 TVF 运算符上时,您会看到属性
IsInterleavedExecuted
设置为 True,以及可能非常接近真实情况的估计行数。欢呼。当没有发生交错执行时,是否有任何扩展事件可以排除故障?
是的,一大堆:
请注意,其中一些位于调试通道中,在搜索要扩展的事件时默认情况下不会选择该通道。
交错执行是否需要 ColumnStore 索引?
不,他们会以任何方式工作。这是一个例子:
这些查询各自连接到不同的表。一个 ColumnStore,一个不是。他们都获得了交错执行计划。
交错执行什么时候起作用?
目前,它仅适用于 MSTVF,其中关联是在函数之外完成的。
这里有几个例子:
此函数没有内部关联,这意味着没有
WHERE
基于表列和传入变量的子句。这个函数是相反的,在
UserId
带有传入变量的列上有一个谓词。这是一个
CROSS APPLY
行不通的常见误解。真正的限制在前面已经提到。内部功能相关性是交易破坏者。