在这篇出色的文章中,Paul演示了并行计划中的分支。
https://sqlperformance.com/2013/10/sql-plan/parallel-plans-branches-threads
在最细粒度的级别上,我们可以使用sys.dm_os_tasks查看任务
是否有一种将任务与分支联系起来的方法?是否有确定当前请求的分支数的方法?
发布于 2019-07-18 14:07:00
是否有确定当前请求的分支数的方法?
您可以通过这样的查询获取该信息:
SELECT
r.session_id,
r.dop,
r.parallel_worker_count
FROM sys.dm_exec_requests r
WHERE r.session_id = 62;
注意,62没有什么特别之处,这正是我的并行查询正在运行的地方。
您可以看到这个查询在DOP 4上运行,并行工作数为12,这意味着该查询可能有3个并行分支。在本例中,肯定是这样的,因为我正在重用来自我的博客文章CXCONSUMER等待的演示查询:

我不知道这是如何工作的,如果Server的预订量低于DOP * branches --保罗在链接到的博客文章中描述了这种情况:
阻塞操作符的存在意味着一个或多个并行分支可以保证在其他分支开始之前完成。在发生这种情况时,Server可以重用用于处理已完成分支的线程,以便在序列中为后面的分支进行处理。SQL Server对于线程预留非常保守,因此只有保证在另一个线程开始之前完成的分支才能使用此线程保留优化。
关于你的另一个问题:
是否有一种将任务与分支联系起来的方法?
保罗对另一个问题的回答详细介绍了这一点:在服务器中可视化并行线程使用的最简单和最精确的方法是什么?
查询将线程与分支关联的方式是通过"nodeId“属性进行的,您可以在查询的执行计划中通过在不同的操作符上悬停找到这个属性。
据我所知,在执行计划中没有明确的内容来标识分支,它们从哪里开始和结束,或者哪些节点属于它们。只知道分支是由exchange操作符所限制的。
如果您真的想为运行中的请求“分配”一个数字给不同的分支,您可以将exec_context_id除以dop,让它四舍五入到最接近的整数。
根据链接的答案修改Paul的查询,这个想法如下所示:
DECLARE @session_id smallint = 51;
SELECT
DOT.task_state,
DOT.scheduler_id,
DOT.exec_context_id,
CASE
WHEN DOT.exec_context_id = 0 THEN 'N/A'
ELSE CONVERT(varchar(3), ((DOT.exec_context_id - 1) / DER.dop) + 1)
END AS branch_id,
DEQP.physical_operator_name,
DEQP.node_id,
DEQP.thread_id,
DEQP.row_count,
DOWT.wait_duration_ms,
DOWT.wait_type,
DOWT.resource_description
FROM sys.dm_os_tasks AS DOT
INNER JOIN sys.dm_exec_requests DER
ON DOT.session_id = DER.session_id
OUTER APPLY
(
-- What each thread did most recently
SELECT *
FROM sys.dm_exec_query_profiles AS DEQP
WHERE
DEQP.session_id = DOT.session_id
AND DEQP.request_id = DOT.request_id
AND DEQP.task_address = DOT.task_address
ORDER BY
DEQP.last_active_time DESC
OFFSET 0 ROWS FETCH FIRST 1 ROW ONLY
) AS DEQP
OUTER APPLY
(
-- Longest wait, if any
SELECT *
FROM sys.dm_os_waiting_tasks AS DOWT
WHERE
DOWT.session_id = DOT.session_id
AND DOWT.exec_context_id = DOT.exec_context_id
ORDER BY
DOWT.wait_duration_ms DESC
OFFSET 0 ROWS FETCH FIRST 1 ROW ONLY
) AS DOWT
WHERE
DOT.session_id = @session_id
--AND DOT.task_state = N'RUNNING'
ORDER BY
DEQP.node_id,
DOT.exec_context_id;
https://dba.stackexchange.com/questions/243204
复制相似问题