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

Dav*_*ash 4 oracle oracle11g

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

从我在各种以Oracle为中心的网站上看到的内容,一些Oracle"专家"建议AGAINST在生产代码中加入优化器提示,因为:

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

一位"专家"说:

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

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

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

Jus*_*ave 6

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

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

当然,在单个查询上打了一个创可贴,如果你不花时间去理解为什么统计数据会将优化器发送到错误的路径,或者为什么你的计划稳定性的方法不起作用,那么很可能是您遇到的统计问题会导致其他查询执行不佳.很少有误导性的统计数据会导致系统中的一个查询表现不佳.通常,这会导致一个粘性循环,其中更多查询开始表现不佳导致更多提示被添加或者一个良性循环,DBA退后一步,解决出错导致查询性能受损,修复底层问题,以及然后删除提示.

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