【问题标题】:Stored procedures and OPTIMIZE FOR UNKNOWN存储过程和 OPTIMIZE FOR UNKNOWN
【发布时间】:2011-05-20 03:02:47
【问题描述】:

我已经阅读了 SQL Server 2008 OPTIMIZE FOR UNKNOWN 查询提示。我了解它的工作原理。

但是,我有一个关于 wherewhen 使用它的问题。它不能在 UDF 中指定。它可以在存储过程中指定。但是,this MSDN 博客文章声明如下:

4.将查询移动到存储过程中可以把它放到一个单独的 程序上下文,可以是一个很好的 使该值对 优化器(注意:这适用于 SQL 2000 年也是如此)

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

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

有人可以为我回答这个问题吗,最好是指向微软的一些东西来解决这个问题。谢谢。

【问题讨论】:

    标签: sql-server stored-procedures query-hints optimizer-hints


    【解决方案1】:

    SQL 编译器的默认行为是使用在第一次执行 SP 时给出的任何参数的值来帮助优化计划(请参阅this MSDN article on SP recompilation 的第 2 和 3 段)。然后缓存该计划以供重复使用,直到它离开缓存 - 计划缓存过程的许多细节here

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

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

    2 如果你发现优化器是 随着时间的推移选择不同的计划 有不同的表现 特点,考虑使用 参数提示与代表 “平均”价值,以获得良好的,共同的 将合理工作的查询计划 所有值。

    但编译器不会选择平均值或代表值,而是完全忽略参数值。

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

    【讨论】:

    • 谢谢@Ed。因此,SQL Server 将在第一次执行时“嗅探”参数并缓存结果计划,并且在此之后不会再嗅探它们,在某些情况下保存它认为有必要制定一个新计划。我做对了吗?
    • @Ed 这为我解决了问题,谢谢。在我看来,一个人几乎应该总是使用提示,否则就会任由执行的第一个计划摆布,这可能会或可能不会接近最佳状态。事实上,考虑到新数据库上的标识值可能较低,几乎可以保证计划中会跳过索引查找。
    猜你喜欢
    • 2021-12-27
    • 2011-05-21
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    • 2014-09-14
    • 2011-07-17
    相关资源
    最近更新 更多