3

我已经阅读了 SQL Server 2008 OPTIMIZE FOR UNKNOWN 查询提示。我明白它是如何工作的。

但是,我有一个关于何时地使用它的问题。它不能在 UDF 中指定。它可以在存储过程中指定。但是,MSDN 博客文章指出以下内容:

4.将查询移动到存储过程中可以将其放入单独的过程上下文中,并且可以是使优化器看到该值的好方法(注意:这在 SQL 2000 中也适用)

在我看来,这似乎是说传递给存储过程的任何参数都将被“嗅探”,从而帮助 SQL Server 编译最佳执行计划。这意味着将重新访问/重新编译缓存的计划(不确定该机制)。然而,这令人困惑,因为它否定了 OPTIMIZE FOR UNKNOWN 的全部需求。

关于查询提示的 MSDN 文章没有涵盖我的问题。

有人可以为我回答这个问题,理想情况下,可以用指向微软的东西来解决这个问题。谢谢。

4

1 回答 1

8

SQL 编译器的默认行为是使用在 SP 的第一次执行中给定的任何参数的值来帮助优化计划(请参阅这篇 MSDN 文章关于 SP 重新编译的第 2 和第 3 段)。然后缓存该计划以供重复使用,直到它离开缓存 -这里有很多关于计划缓存过程的详细信息。

您引用的 MSDN 博客指出了使编译器更容易执行此过程的方法;我认为第 4 项(在问题中引用)表明这是存储过程相对于 ad-hoc SQL 的优势。

提示指示编译器OPTIMIZE FOR UNKNOWN避免默认行为;它应该忽略第一次执行中给出的参数值并选择更通用的计划。这是问题中引用的博客文章末尾的建议列表中第 2 项的更极端版本;

2 如果您发现优化器随着时间的推移选择具有不同性能特征的不同计划,请考虑使用具有代表性“平均值”值的参数提示来获得一个良好、通用的查询计划,该计划将合理地适用于所有值。

但不是选择平均值或代表值,编译器将有效地完全忽略参数值。

考虑OPTIMIZE FOR UNKNOWN在第 2 项中引用的情况下使用 - 当相同的查询提供非常可变的性能时,因为计划在某些情况下很差 - 通常是当查询中的参数过滤掉基数非常可变的列时。

于 2010-12-04T09:02:33.390 回答