DBK*_*DBK 4 sql-server execution-plan recompile query-performance
我在使用和不使用 OPTION (RECOMPILE) 的情况下执行了相同的查询。当我比较这两个计划时,我看到的一个主要区别是,没有选项重新编译的计划显示了很多 ComputeScalar 运算符,而另一个则没有。
以下是两个计划:
不带选项重新编译:https://www.brentozar.com/pastetheplan/ ?id=S1OcZGi85 带选项重新编译:https://www.brentozar.com/pastetheplan/ ?id=ryJAfMsL5
为什么一个计划使用大量计算标量,而另一个计划则不使用?不带选项重新编译的查询需要近 4 分钟才能执行。计算标量操作是否导致速度缓慢?
编译器正在采用您的IN
子句并尝试通过删除重复值来进行优化。它通过获取所有参数、对它们进行排序、使用 来按顺序合并它们Merge Interval
,并对Nested Loop Join
结果执行 a 操作来实现此目的。
问题是,这可能需要很长的时间来编译大量值:每个值都需要自己的虚拟表,导致最后出现 aConstant Scan
和 aCompute Scalar
以及一个 big 值。Concatenation
这就是在运行查询之前导致编译时速度减慢的原因。
同时,该OPTION (RECOMPILE)
版本可以将参数直接嵌入到查询中,这意味着在编译的优化阶段开始之前这些值将被折叠在一起,从而显着加快整体编译时间。这是以每次运行时重新编译为代价的。
所有这一切的结果是IN
,很长的列表以及大量的参数可能会非常低效。
我建议您考虑使用表值参数、临时表或表变量(在所有情况下都使用主集群键进行索引),并以正常方式简单地加入它们。
至于实际的查询本身,有很多奇怪的事情。
COUNT(*)
的,所以不清楚巨人PIVOT
最初的意义是什么,相对于正常的GROUP BY
.LEFT JOIN
不呢INNER JOIN
?连接列可以为空吗?CROSS APPLY
没有应用任何外部引用,它可能是CROSS JOIN
,并且其本身在查询中没有任何作用。 归档时间: |
|
查看次数: |
351 次 |
最近记录: |