第一个计划中的假脱机迭代器是否有任何合理的好处?
这取决于您认为“合理”的条件,但是根据成本模型得出的答案是肯定的。当然这是正确的,因为优化器总是选择找到的最便宜的计划。
真正的问题是,为什么成本模型认为带线轴的计划比不带线轴的计划便宜得多。在将任何行添加到增量存储之前,请考虑为新表(通过脚本)创建的估计计划:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE);
该计划的估计成本为771,734单位的巨额资金:
成本几乎全部与聚集索引删除相关,因为删除预计会导致大量的随机I / O。这只是适用于所有数据修改的通用逻辑。例如,假设对b树索引的无序修改集会导致大量的随机I / O,并伴有较高的I / O成本。
正是出于这些成本原因,数据更改计划可能具有“排序”功能,以便按顺序显示行,从而促进顺序访问。在这种情况下,由于表已分区,因此影响更加严重。实际上,它非常分区。您的脚本创建了15,000个脚本。由于对中游切换分区(行集)的代价也很高,因此对一个非常分区的表进行随机更新的代价特别高。
最后要考虑的主要因素是,上面的简单更新查询(其中“更新”表示任何数据更改操作,包括删除)均符合称为“行集共享”的优化条件,其中,相同的内部行集用于扫描和更新表。执行计划仍显示两个单独的运算符,但是,仅使用了一个行集。
我之所以这么说是因为能够应用此优化意味着优化器采用的代码路径根本没有考虑显式排序的潜在好处,从而降低了随机I / O的成本。在表是b树的情况下,这是有道理的,因为结构固有地是有序的,因此共享行集会自动提供所有潜在的好处。
重要的结果是,更新运算符的成本核算逻辑不会考虑基础对象为列存储的这种排序优势(促进顺序I / O或其他优化)。这是因为列存储修改未就地执行;他们使用增量存储。因此,成本模型反映了b树上的共享行更新与列存储之间的差异。
但是,在(非常!)分区列存储的特殊情况下,保留顺序可能仍然有好处,因为从I / O角度来看,在移至下一个分区之前对一个分区执行所有更新可能仍然是有利的。 。
标准的成本逻辑可在此处重新用于列存储,因此保留分区顺序(尽管不是每个分区内的顺序)的计划的成本较低。通过使用未记录的跟踪标志2332要求对更新操作符进行排序的输入,我们可以在测试查询上看到这一点。这会将DMLRequestSort
属性在更新时设置为true,并迫使优化器生成一个计划,该计划为一个分区提供所有行,然后再移至下一个分区:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332);
该计划的估计成本要低得多,为52.5174个单位:
成本的降低全部归因于更新时估算的I / O成本较低。引入的后台打印程序不执行任何有用的功能,只是它可以保证按更新的要求按分区顺序输出DMLRequestSort = true
(列存储索引的串行扫描无法提供此保证)。线轴本身的成本被认为是相对较低的,尤其是与更新时的成本降低(可能不切实际)相比。
在查询优化中非常早就做出了是否需要对更新操作符进行有序输入的决定。该决策中使用的启发式方法从未被记录下来,但是可以通过反复试验来确定。似乎任何增量存储的大小都是此决定的输入。做出选择后,该选择对于查询编译是永久的。没有任何USE PLAN
提示会成功:计划的目标或者已经命令了更新的输入,或者没有。
还有一种方法可以为该查询获取低成本计划,而无需人为地限制基数估计。避免假脱机处理的足够低的估计值可能会导致DMLRequestSort为假,由于预期的随机I / O导致非常高的估计计划成本。另一种选择是将跟踪标志8649(并行计划)与2332(DMLRequestSort = true)结合使用:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332, QUERYTRACEON 8649);
这将导致一个计划,该计划使用按分区的批处理模式并行扫描和顺序保留(合并)的Gather Streams交换:
根据您的硬件上分区排序的运行时有效性,这可能会在三种方法中表现最好。也就是说,对列存储进行大的修改并不是一个好主意,因此分区切换的主意几乎可以肯定更好。如果您可以应对分区对象经常出现的长编译时间和古怪的计划选择,尤其是在分区数量很大的情况下。
结合许多相对较新的功能,尤其是接近其极限,是获得不良执行计划的好方法。优化程序支持的深度会随着时间的推移而不断提高,但是使用15,000个列存储分区可能总是意味着您生活在有趣的时期。
OPTION (QUERYRULEOFF EnforceHPandAccCard)
,线轴将消失。我认为惠普可能是“万圣节保护”。但是,然后尝试使用带有USE PLAN
提示的计划失败了(就像尝试通过OPTIMIZE FOR
变通办法使用该计划一样)