为什么CTE(递归)没有并行化(MAXDOP=8)?

2024-01-06

我们有相当大的机器 100GB+ 内存和 8+ 核心。服务器范围 MAXDOP=8。

T_SEQ_FF rowcount = 61692209, size = 2991152 KB  

UPD 1: Table T_SEQ_FF有两个索引:

1) create index idx_1 on T_SEQ_FF (first_num)
2) create index idx_2 on T_SEQ_FF (second_num)

Table T_SEQ_FF have first_num, second_num pairs应在 cte 之后提供序列的 nums:

;with first_entity as ( 
    select first_num from  T_SEQ_FF a  where not exists (select 1 from  T_SEQ_FF b  where a.first_num = b.second_num) 
) ,
cte as ( 
select a.first_num, a.second_num, a.first_num as first_key, 1 as sequence_count 
from  T_SEQ_FF a  inner join first_entity b on a.first_num = b.first_num 
union all 
select a.first_num, a.second_num, cte.first_key, cte.sequence_count + 1 
from  T_SEQ_FF a  
inner join cte on a.first_num = cte.second_num 
) 
select * 
from cte 
option (maxrecursion 0); 

但是当我运行这个查询时 - 我只看到串行查询计划而没有并行性。 如果我remove上面查询的 CTE 的第二部分:

union all 
    select a.first_num, a.second_num, cte.first_key, cte.sequence_count + 1 
    from  T_SEQ_FF a  
    inner join cte on a.first_num = cte.second_num 

然后我可以看到查询计划变成并行化使用重新分区和收集流。

所以我可以总结一下这是因为递归的CTE SQL Server 在处理此查询时未使用并行性。

我相信,在拥有大量免费资源的大型机器上,并行性应该有助于更快地完成查询。

目前它的运行时间约为 40-50 分钟。

您能否建议如何使用尽可能多的资源来更快地完成查询?

CTE 是唯一的选择,因为我们需要从以下位置填充序列first_num - second_num对和这些序列可以是任意长度。


我会尝试重写 CTE 以删除其中一个步骤,即

;cte as ( 
select a.first_num, a.second_num, a.first_num as first_key, 1 as sequence_count 
from  T_SEQ_FF a  where not exists (select 1 from  T_SEQ_FF b  where a.first_num = b.second_num) 
union all 
select a.first_num, a.second_num, cte.first_key, cte.sequence_count + 1 
from  T_SEQ_FF a  
inner join cte on a.first_num = cte.second_num 
) 
select * 
from cte 
option (maxrecursion 0);

如果只有一个根元素,最好将其作为变量传递到查询中,以便查询优化器可以使用该值。

另一件要尝试的事情是更改查询以获取没有子查询的根元素,即 secondary_num 为 null 或first_num = secondary_num。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么CTE(递归)没有并行化(MAXDOP=8)? 的相关文章

随机推荐