我们知道,备忘录结构已修剪,并且在优化过程中放弃了一些昂贵的替代计划。我想知道是否有任何方法可以防止这种情况,让优化器考虑所有可能的计划并从所有替代方案中选择最佳方案?
a hash join b
成本为10或更多,那么为什么要计算所有这些百万个计划而不修剪呢?(不是优化在这样一个简单的工作方式)
我们知道,备忘录结构已修剪,并且在优化过程中放弃了一些昂贵的替代计划。我想知道是否有任何方法可以防止这种情况,让优化器考虑所有可能的计划并从所有替代方案中选择最佳方案?
a hash join b
成本为10或更多,那么为什么要计算所有这些百万个计划而不修剪呢?(不是优化在这样一个简单的工作方式)
Answers:
我们知道,备忘录结构已修剪,并且在优化过程中放弃了一些昂贵的替代计划。我想知道是否有任何方法可以防止这种情况,让优化器考虑所有可能的计划并从所有替代方案中选择最佳方案?
有,但是我不公开,因为它会被误解和误用。无论如何,这不会导致对计划空间的详尽搜索,因为仅实施了一组有限的转换(通常会产生良好结果的转换)。
防止修剪和丢弃通常只会导致(很多)更长的编译时间,而对最终计划的质量(如果有的话)没有太大的改善。
最终,这个问题是自然而合理的问题,但它是基于对SQL Server查询优化器目标的误解:它旨在快速找到常见查询的良好计划。它不是建立在旨在穷举搜索的框架上。
如果您在现实环境中会受益于不同的优化方法,则可以在Connect网站上找到理由(尽管我确实认为Microsoft不太可能会投资必要的工程资源)。
我知道没有任何旋钮或跟踪标志可以以任何方式强制这种行为(尽管Paul White在这里提到了一些跟踪标志,这些标志提供了更多的可见性并允许您哄骗某些行为增量)。
微软提供了很多武器,但是几乎可以保证这100%的时间都是直指您自己的脚。第一次运行查询时,我认为您不希望SQL Server花无数的时间来构造计划的每个可能的变体,以获得所需的结果。作为@ypercube提到,这可能是一个非常大的数量的计划,并且将那种失败的运行在所有查询的目的。首先,您运行查询的目标可能是在某个时候返回数据,对吧?而且“某个点”必须在一定的阈值之内,因为您的应用程序的某些层将强制执行各种查询/命令超时,并且用户只需等待很长时间即可加载页面...