查询优化器创建多个可能的执行计划。如何查看在选择执行的计划之前生成的所有计划?
微软说:
查询优化器必须分析可能的计划并选择估计成本最低的计划。
请注意,我不是在谈论执行计划缓存和重用,而是在谈论候选执行计划,即那些已生成但未选择执行的执行计划。
根据 Benjamin Nevarez 的文章The SQL Server Query Optimizer:
候选执行计划的生成是在查询优化器内部使用转换规则执行的,启发式方法的使用限制了考虑的选择数量,以保持优化时间合理。候选计划在优化期间存储在内存中的一个称为备忘录的组件中。
是否有可能以我们可以显示实际执行计划的方式可视化呈现的候选计划?
如果优化器认为它们比目前在搜索中看到的最佳解决方案更差,则优化器具有启发式方法,通过在完全探索之前丢弃计划和部分计划来减少搜索时间。因此,它实际上并没有完全生成所有替代方案。此外,XML 表示实际上是在搜索结束时生成的——内部表示有些不同。不幸的是,目前没有公共功能可供您探索同一查询的其他可能计划。使用调试器,我们可以查看在优化过程中包含所有这些的结构。它被称为备忘录。您可以在此处阅读有关 SQL 优化器所基于的 Cascades 框架的更多信息
据我所知,没有办法查看最终被丢弃的候选计划的图形/ XML 执行计划。如果您期望某种计划形状,一种方法是使用提示,然后比较成本,以了解为什么选择最终计划而不是提示计划。
例如,您可能期望某个非聚集索引将用于查询的一部分,但最终计划改为扫描聚集索引。向查询添加
WITH (INDEX (IX_Your_Index))
表提示可以向您展示该索引的结果。有很多提示可以用于此目的。不过,您可以看到很多带有提示索引和连接的选项。除了完整的执行计划之外,还有一些方法可以查看有关优化过程的更多详细信息、优化器如何转换查询以及考虑、选择或丢弃的不同计划片段。Paul White 的Query Optimizer Deep Dive系列对此进行了相当多的详细介绍。
如果您想可视化查询的“逻辑树”是如何转换和简化的(如 Paul 系列的第 1 部分中所讨论的),有一个简洁的免费工具:SQL Server Query Tree Viewer
本系列的第 3 部分讨论了“中间”计划以及如何通过优化器的 memo 数据结构查看有关它们的一些信息。
我知道这些都不是特别简单,但希望它有助于您理解为什么某些计划可能会被其他计划抛弃!不管怎样,我发现上面链接的所有文章都很有趣?