当前位置: 首页 > 面试题库 >

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

桑博远
2023-03-14
问题内容

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

T_SEQ_FF rowcount = 61692209, size = 2991152 KB

UPD 1: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)

表格T_SEQ_FF中的first_numsecond_num pairs有num个,应在cte之后提供一个序列:

;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);

但是,当我运行此查询时,我只会看到没有并行的串行查询计划。如果我从上述查询中 删除 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

然后我可以看到使用Repartition和Gather Streams使查询计划成为 并行化

因此,我可以总结一下,这是因为 recurisve 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);

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

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



 类似资料:
  • 问题内容: 我正在尝试执行我认为使用CTE进行递归比较困难的事情是SQL Server 2008。 在下面的示例中,您可以假设固定深度为3 …没有任何比这更低的深度了。在现实生活中,深度是“更深的”,但仍然是固定的。在示例中,我尝试将其简化一些。 我的输入数据如下。 我的CTE的输出应为下表。 如果我可以在输出中获得ID列,则可以肯定地可以映射到查找表中的名称。 我也乐于接受其他方法来完成此任务,

  • 问题内容: 假设具有以下CTE,这些CTE返回我已经拥有的某些树数据(邻接模型)的级别(取自Linq中的分层数据- options和performance): 我想知道通过使用C#而不是SQL进行递归是否会提高性能。假设我有一个IQueryable,其中Tree是表示层次结构表中条目的实体,谁能向我展示如何执行CTE与递归C#函数相同的工作?类似于以下内容: 看到使用lambda表达式很容易做到这

  • 问题内容: 此查询生成从1到4的数字。 但是,如果我对此进行修改, 它给 错误:“ z”处或附近的语法错误 我在这里做错了什么? 问题答案: 我认为这是因为RECURSIVE是WITH语句的修饰符,而不是常用表表达式的属性,因此您可以像这样使用它:

  • 问题内容: 我一直在尝试将编程的递归作为一个概念进行研究(尽管我专门研究Java),而这正是我最好的理解: 例如,在现实生活中,递归是当我们将两个反射镜彼此相对放置并且它们之间产生的图像是递归的。 但是我在编程中没有得到这个算法吗?有人可以给我一个简化的例子来理解递归吗? 问题答案: 基本上,函数是递归的 函数具有简单的基本情况,何时 所有其他情况都有规则化简为基本情况。 例如,要计算阶乘:

  • 问题内容: 我正在使用SQL Server 2008 R2 SP1。我想通过“走树”来递归地为某个组织单位找到第一个非空经理。 我有一个包含组织单位“ ORG”的表,一个包含每个组织的父母的表。“ ORG”中的部门,将其称为表“”,其中一个表包含每个组织部门的经理,将其称为“ ”。 ORG具有一列ORG_ID: ORG_PARENTS有两列。 管理器有两列。 我正在尝试创建一个递归查询,该查询将为

  • 问题内容: 在这个sqlfiddle中… http://sqlfiddle.com/#!6/b6587/6 我收到以下错误…。 声明终止。在语句完成之前,最大递归100已用尽。 我知道CTE第二选择的where子句中需要进行“终止检查”。即使您取消注释WHERE子句,我也会遇到相同的错误。 我只是想了解1)为什么根本需要它……毕竟每个订单行都与每个客户行都有关系,2)由于需要“终止检查”,因此该示