无法在 SQL Server 上并行运行联合

cro*_*sek 3 sql-server union

我无法得到这个相当简单的查询来并行化联合操作:

select va.ObjectId, 0 as IsFlag
  from Oav.ValueArray va     
 where va.PropertyId = @pPropertyId                
   and va.value in (select value from #MatchValues)                  
 group by va.ObjectId
having count(distinct va.Value) = (select count(*) from #MatchValues)

union all    

select odv.ObjectId, 1 as IsFlag
  from Pub.OtherTable codv
 where PropertyId = 2551
   and Id in (select value from #Ids) 
   and Flag = @pFlag
   and Value in (select value from #MatchValues)
 group by codv.ObjectId
having count(distinct codv.Value) = (select count(*) from #MatchValues)
Run Code Online (Sandbox Code Playgroud)

使用 MAXDOP 1 运行会得到预期的 0.8s (.5 + .3)。我希望将 MAXDOP 增加到 2 可以通过为每一侧使用一个处理器来优化最大的收益,但事实并非如此。Maxdop 零在轻载 12 Cpu 机器上全部 ~4% 仅导致大约 10% 的时间并行执行。

有没有办法对提示进行加权,以便联合点的并行化最重要?语法是否支持每边单独的 MAXDOP?

我尝试过(concat/hash/merge union),几乎没有什么变化。

匹配值通常是一个小表(~10 行)。

Aar*_*and 7

MAXDOP每边都没有单独的。但你可以玩:

OPTION (QUERYTRACEON 8649)
Run Code Online (Sandbox Code Playgroud)

这将并行的成本阈值设置为 0,这意味着即使成本非常低,它也会考虑并行计划。您也可以使用DBCC SETCPUWEIGHTPaul White 在此处描述的他在此处用于强制执行并行计划的其他技术。甚至玩DBCC OPTIMIZER_WHATIF- 这真的应该只是为了玩。

有一个关于 Connect 的建议允许使用MINDOP语法或类似的东西

无论如何,我不相信并行性在这种情况下一定会帮助您。当然,您可能会得到一个并行计划,但它真的会减少查询的运行时间吗?有了所有这些GROUP BY DISTINCT(为什么您需要两者?)我认为您应该将优化重点放在其他地方(例如可能预先聚合其中的一些信息)。或者甚至是一些简单的事情,比如可能将 分配COUNT(*) FROM #MatchValues给一个变量而不是尝试对它求值两次(不确定在这种情况下 SQL Server 是否会这样做,但消除诱惑并没有什么坏处)。