Eri*_*ing 4 sql-server functions sql-server-2017 interleaved-execution
Interleaved Execution 是2017 查询处理器中一系列功能的一部分,其中包括:
那么交错执行是如何工作的呢?
魔鬼在表变量中
交错执行旨在解决多语句表值函数中错误估计的正确基数。
在 SQL Server 的早期版本中,这些函数总是会产生相当粗劣的估计:
不用说,这在加入其他表时可能会导致很多问题。
虽然从表变量中选择数据本身不会抑制并行性,但低行估计通常会导致查询成本低,而并行性不会被考虑。
使用交错执行时,基数估计会暂停,MSTVF 的子树会被执行,并使用更准确的基数估计恢复优化。
我如何知道我的 MSTVF 是否接收交错执行。
与自适应连接一样,交错执行也在查询计划中注明。与 Adaptive Joins 不同,它没有在估计的计划中注明,至少在撰写本文时是这样。
具有交错执行的 MSTVF 的计划形状与其中包含 MSTVF 的典型计划略有不同。
您将看到计划顶部的表值函数运算符,以及 TVF 运算符通常位于图形计划中的表变量的扫描。
将鼠标悬停在 TVF 运算符上时,您将看到该属性IsInterleavedExecuted
设置为 True,以及可能非常接近真实情况的估计行数。欢呼。
当不发生交错执行时,是否有任何扩展事件可以进行故障排除?
是的,一大堆:
请注意,其中一些位于调试通道中,在搜索要扩展的事件时默认情况下未选择该通道。
交错执行是否需要列存储索引?
不,无论哪种方式,它们都会起作用。下面是一个例子:
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';
Run Code Online (Sandbox Code Playgroud)
这些查询各自连接到不同的表。一个 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
Run Code Online (Sandbox Code Playgroud)
这个函数是相反的,在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
Run Code Online (Sandbox Code Playgroud)
这是CROSS APPLY
行不通的常见误解。前面已经提到了真正的限制。内部函数相关性是交易破坏者。
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;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
423 次 |
最近记录: |