Oracle优化器在生产代码中是否明智?

时间:2015-03-02 17:55:45

标签: oracle oracle11g

当我开始加速Oracle(在过去的几十年里一直是DB2家伙)时,我看到很多现有的代码在其查询中使用了优化器提示。

从我在各个以Oracle为重点的网站上看到的,几位Oracle"专家"建议AGAINST在生产代码中加入优化器提示,因为:

  • 对于每个Oracle补丁或升级,提示可能都是错误的。
  • 对于每个DDL,提示可能都是错误的。

一个"专家"表示:

  

警惕暗示的原因是,通过在SQL中嵌入提示,您将覆盖优化器并说您知道的比实时更多 - 不仅仅是现在,而是将来每次运行SQL都会运行,无论您的数据库可能发生任何其他变化。这可能导致您的SQL现在可能会以次优的方式运行,而且几乎肯定会在将来运行。

(见http://allthingsoracle.com/a-beginners-guide-to-optimizer-hints/

因此,如果通常知道优化器提示是“不明智的”,那么为什么它们经常被使用(至少在我看过的代码中)?

2 个答案:

答案 0 :(得分:6)

如果提示很常见,通常是因为过去有人优先解决严重问题而不是处理潜在的统计问题。完全可能的是,这种优先顺序是合理的(特别是在当时),但它引入的技术债务可能需要偿还。

当系统由于查询计划发生变化而变得无法响应并且效率大大降低时,修复严重生产问题通常优先于确定根本原因。对单个查询进行提示通常比找出根本问题更快更容易,或者学习如何使用Oracle提供的各种工具来确保查询计划的稳定性或随着时间的推移制定计划。

当然,在单个查询上打了一个创可贴,如果你不花时间去理解为什么统计数据会将优化程序发送到错误的路径上,或者为什么你的计划稳定性的方法没有。无论你遇到什么统计问题,都可能会导致其他查询表现不佳。非常罕见的误导性统计数据只会导致系统中的一个查询表现不佳。通常,这会导致一个粘性循环,其中更多查询开始表现不佳导致更多提示被添加,或者一个良性循环,DBA退后一步,通过错误导致查询性能受损,修复基础问题,然后删除提示。

所有这一切,根据您使用的代码类型,有一些相对常见的合理使用提示。如果您有一个返回sys_refcursor的函数,该函数返回给您知道将要获取前几行的客户端应用程序,请将其显示给用户,并仅询问下一组行如果他们找不到他们正在寻找的东西,那么使用FIRST_ROWS提示是非常有意义的,因为你知道优化器可能知道的东西。您知道用户对前几行而不是完整的结果集更感兴趣。如果你有很多代码在SQL中使用集合,你可能想要使用大量的CARDINALITY提示,否则Oracle不知道集合可能有多少元素。

答案 1 :(得分:0)

就我而言,我在生产代码中看到的大部分提示都是这样的:

/*+APPEND*/
/*+ full(MP) parallel(MP, 16) */
/*+ PARALLEL(ME1, 16) FULL(ME1) DRIVING_SITE(ME1) */ 

很少(但经常),我会看到索引提示:

e.g。

/*+ index(MSL XCL01000) */ 

感谢您的宝贵意见。我当然明白了提示的危险和必要性。