为什么 sys.dm_exec_query_profiles 返回的某些行有“???” 对于物理运营商名称?

Joe*_*ish 7 sql-server execution-plan sql-server-2016

SQL Server 2014 引入了sys.dm_exec_query_profiles DMV,它提供了一种监视执行查询的实时进度的方法。最近我在查看 SQL Server 2016 SP1 中的一个有点复杂的查询,并注意到它sys.dm_exec_query_profiles包含查询计划中不存在的额外节点。这些节点必须???physical_operator_name

???

对于查询的并行版本,只有一个隐藏节点。该节点有一个object_id与嵌套循环连接的内表相关联。根据node_id这里是节点应该出现的地方:

平行线 ???

运行查询会MAXDOP 1产生更多的隐藏节点。该???节点出现在与之前相同的位置:

序列 1 ???

还有一个新的没有出现在平行计划中:

系列 2 ???

这些似乎只出现在一些嵌套循环连接周围。我不记得在 SQL Server 2014 上看到过这种行为。不幸的是,查询很复杂,我无法上传匿名计划。

这里发生了什么?为什么sys.dm_exec_query_profiles报告没有显示在图形计划中的额外查询计划节点?

Joe*_*ish 7

批处理模式适配器(位于行处理切换到批处理或其他方式的查询计划中)???在 DMV 中显示为athread_id为 0。但是,示例查询不使用批处理,因此不是原因在这里。

嵌套循环预取也可能导致sys.dm_exec_query_profiles. 有一个用于禁用嵌套循环预取的记录跟踪标志

跟踪标志 8744 禁用嵌套循环运算符的预取。

当 SQL Server 执行包含嵌套循环运算符的计划时,不正确使用此跟踪标志可能会导致额外的物理读取。有关嵌套循环运算符的详细信息,请参阅 SQL Server 2005 联机丛书中的“逻辑和物理运算符参考”主题。

如果我向查询添加查询提示,QUERYTRACEON 8744???节点不再出现。

对于嵌套循环预取的可重现示例,我将借用 Paul White 在他的嵌套循环预取文章中针对 Adventure Works 的示例:

SELECT TOP (1000)
    P.Name,
    TH.TransactionID
FROM Production.Product AS P
JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID
WHERE
    P.Name LIKE N'[K-P]%'
ORDER BY 
    P.Name, 
    TH.TransactionID;
Run Code Online (Sandbox Code Playgroud)

如果我对 SQL Server 2016 SP1 运行该查询并快速捕获输出,sys.dm_exec_query_profiles我会得到以下结果:

SELECT TOP (1000)
    P.Name,
    TH.TransactionID
FROM Production.Product AS P
JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID
WHERE
    P.Name LIKE N'[K-P]%'
ORDER BY 
    P.Name, 
    TH.TransactionID;
Run Code Online (Sandbox Code Playgroud)

如果我在 SQL Server 2014 中运行相同的查询,我会得到以下结果:

?????????????????????????????????????????????????????????????????????
?    OBJECT_NAME     ? physical_operator_name ? node_id ? thread_id ?
?????????????????????????????????????????????????????????????????????
? NULL               ? Top                    ?       0 ?         0 ?
? NULL               ? Nested Loops           ?       1 ?         0 ?
? TransactionHistory ? ???                    ?       2 ?         0 ?
? Product            ? Index Seek             ?       3 ?         0 ?
? TransactionHistory ? Index Seek             ?       4 ?         0 ?
?????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,都会发生嵌套循环预取优化。似乎只有 SQL Server 2016 报告了它,但这可以解释为什么我从未在 SQL Server 2014 中看到过这种情况。