我无法获得这个相当简单的查询来并行化联合操作:
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)
使用 MAXDOP 1 运行会产生预期的 0.8 秒 (.5 + .3)。我希望将 MAXDOP 增加到 2 可以通过为每一侧使用一个处理器来优化最大收益,但事实并非如此。在轻负载的 12 Cpu 机器上的 Maxdop 为零,所有 ~4% 仅导致大约 10% 的时间并行执行。
有没有办法对提示进行加权,以便联合点的并行化是最重要的?语法是否支持每一侧单独的 MAXDOP?
我尝试过(concat/hash/merge union),变化不大。
匹配值通常是一个小表(约 10 行)。
每边没有单独
MAXDOP
的。但你可以玩:这将并行的成本阈值设置为 0,这意味着即使成本非常低,它也会考虑并行计划。您也可以使用
DBCC SETCPUWEIGHT
Paul White 在此处描述的或他在此处强制并行计划的其他技术。甚至玩DBCC OPTIMIZER_WHATIF
- 这真的应该只是为了玩。有一个关于 Connect 的建议允许使用
MINDOP
语法或类似的东西。无论如何,我不相信并行性在这种情况下一定会对您有所帮助。当然,您可能会得到一个并行计划,但它真的会减少查询的运行时间吗?有了所有这些
GROUP BY
,DISTINCT
(为什么你会同时需要两者?)我认为你应该把优化重点放在其他地方(比如预先聚合一些信息)。或者甚至是一些简单的事情,比如可能将 分配COUNT(*) FROM #MatchValues
给一个变量而不是尝试对其进行两次评估(不确定 SQL Server 在这种情况下是否会这样做,但消除诱惑不会有什么坏处)。