强制并行联合执行
Posted
技术标签:
【中文标题】强制并行联合执行【英文标题】:Force parallel union execution 【发布时间】:2019-08-16 09:13:37 【问题描述】:我有一个从六个相同类型的表中收集数据的查询。为了创建最终选择,我使用 UNION ALL。不幸的是,优化器会依次扫描六个表中的每一个,然后将它们收集到一个表中。有没有办法让优化器并行扫描表?
|--Concatenation
|--Index Scan(OBJECT:([EGeoCache].[NonClusteredIndex-20190815-105027] AS [GC]))
|--Index Scan(OBJECT:([YGeoCache].[NonClusteredIndex-20190814-103125] AS [GC]))
|--Index Scan(OBJECT:([GGeoCache].[NonClusteredIndex-20190814-103358] AS [GC]))
|--Index Scan(OBJECT:([HGeoCache].[NonClusteredIndex-20190814-103422] AS [GC]))
|--Index Scan(OBJECT:([DGeoCache].[NonClusteredIndex-20190814-103305] AS [GC]))
|--Index Scan(OBJECT:([SGeoCache].[NonClusteredIndex-20190814-103457] AS [GC]))
SELECT
VEGC.AddressID
, VEGC.Lat
, VEGC.Lon
FROM vEGeoCache AS VEGC
UNION ALL
SELECT
VYGC.AddressID
, VYGC.Lat
, VYGC.Lon
FROM vYGeoCache AS VYGC
UNION ALL
SELECT
VGGC.AddressID
, VGGC.Lat
, VGGC.Lon
FROM vGGeoCache AS VGGC
UNION ALL
SELECT
VHGC.AddressID
, VHGC.Lat
, VHGC.Lon
FROM vHGeoCache AS VHGC
UNION ALL
SELECT
VDGC.AddressID
, VDGC.Lat
, VDGC.Lon
FROM vDGeoCache AS VDGC
UNION ALL
SELECT
VSGC.AddressID
, VSGC.Lat
, VSGC.Lon
FROM vSGeoCache AS VSGC
【问题讨论】:
这是一个非常好的问题。我不认为有办法让这些并行运行,但我很想知道是否有办法。 由于无法准确复现你的情况,我从多个表中选择了相同类型的字段,并行执行,开启Include LIve Query Statistics
,甚至可以看到并行。
表是否在不同的设备(或内存驻留)上,以便并行执行不会造成 I/O 瓶颈?否则,不清楚您期望从并行执行中获得什么好处。
【参考方案1】:
要强制执行并行执行计划,您可以使用需要系统管理员权限的OPTION (QUERYTRACEON 8649)
。在 SQL Server 2016+ 上,您可以使用不需要系统管理员权限的 OPTION(USE HINT('ENABLE_PARALLEL_PLAN_PREFERENCE'))
。
QUERYTRACEON 8649 和 ENABLE_PARALLEL_PLAN_PREFERENCE 都没有记录,这意味着它们在生产环境中运行是不安全的(在我的书中)。您的第三个选择是使用 Adam Machanic 的Make_Parallel,这不是无证的(它只是使用旧学校的数学)。
使用每个看起来像这样:
...
FROM vDGeoCache AS VDGC
UNION ALL
SELECT
VSGC.AddressID
, VSGC.Lat
, VSGC.Lon
FROM vSGeoCache AS VSGC
OPTION (QUERYTRACEON 8649);
...
FROM vDGeoCache AS VDGC
UNION ALL
SELECT
VSGC.AddressID
, VSGC.Lat
, VSGC.Lon
FROM vSGeoCache AS VSGC
OPTION(USE HINT('ENABLE_PARALLEL_PLAN_PREFERENCE'))
...
FROM vDGeoCache AS VDGC
UNION ALL
SELECT
VSGC.AddressID
, VSGC.Lat
, VSGC.Lon
FROM vSGeoCache AS VSGC
CROSS JOIN dbo.make_parallel();
Make_parallel 是最安全的方法,但会创建一个臃肿的执行计划。
我这样做的方式是:我在 Dev 的测试中使用 OPTION (QUERYTRACEON 8649)
。需要注意的最重要的事情是,这些选项不能保证并行计划。确保在打开“包括实际执行计划”的情况下运行查询,以查看它是否正常工作。如果有任何并行性抑制组件(例如标量 UDF 作为计算列或检查约束),则不会强制执行并行计划。如果我确定强制执行并行计划是可行的方法(强制执行极其谨慎),那么我在生产中使用 make_parallel。
【讨论】:
以上是关于强制并行联合执行的主要内容,如果未能解决你的问题,请参考以下文章