当我开始学习Oracle (在过去几十年中一直是DB2的人)时,我看到了很多在其查询中使用优化器提示的现有代码。
根据我在各种面向甲骨文的网站上所读到的,几位甲骨文“专家”建议不要在生产代码中添加优化器提示,因为:
一位“专家”说:
避免暗示的原因是,通过在SQL中嵌入提示,您将覆盖优化器,并且说您知道的比它更多--不仅是现在,而且每次您的SQL都将运行,而不管数据库中可能发生的任何其他更改。这可能带来的后果是,您的SQL现在可能运行次优化,而且在将来几乎肯定会运行。
(见http://allthingsoracle.com/a-beginners-guide-to-optimizer-hints/)
所以,如果优化器-提示通常被认为是“不明智的”,为什么它们会被如此频繁地使用(.至少在我见过的代码中是这样的)?
发布于 2015-03-02 19:22:57
在某种程度上,提示是常见的,这通常是因为过去有人优先解决一个尖锐的问题,而不是处理潜在的统计问题。这种优先顺序完全有可能是合理的(特别是在当时),但它引入了可能需要偿还的技术债务。
当系统由于查询计划更改而变得没有响应,效率大大降低时,解决严重的生产问题通常优先于确定根本原因。对单个查询发出提示通常比找出根本问题或学习如何使用Oracle提供的各种工具来确保查询计划的稳定性或随着时间的推移发展计划更快、更容易。
当然,如果你没有花时间去理解为什么统计数据会让优化器选择错误的路径,或者为什么你的计划稳定性方法不起作用,那么不管你有什么统计问题,都很可能会导致其他查询表现不佳。非常罕见的是,误导性的统计数据只会导致系统中的一个查询表现不佳。通常,这会导致一个粘稠的循环,导致更多查询开始执行不好,从而导致添加更多提示,或者导致DBA后退一步的良性循环,解决导致查询性能下降的问题,修复根本问题,然后删除提示。
尽管如此,根据您所使用的代码类型,有几个提示可能会被合理地使用。如果有一个函数返回一个返回给客户端应用程序的sys_refcursor
,该应用程序将获取前几行,将其显示给用户,并且只要求下一组行(如果它们找不到要查找的行),那么使用FIRST_ROWS
提示是很有意义的,因为您知道优化器不可能知道的事情。您知道,用户更感兴趣的是前几行,而不是完整的结果集。如果您有大量在SQL中使用集合的代码,您可能希望使用大量的CARDINALITY
提示,因为否则Oracle不知道集合可能有多少元素。
发布于 2015-03-05 00:45:40
在我的例子中,我在生产代码中看到的大多数提示如下所示:
/*+APPEND*/
/*+ full(MP) parallel(MP, 16) */
/*+ PARALLEL(ME1, 16) FULL(ME1) DRIVING_SITE(ME1) */
很少(但偶尔),我会看到一个索引-提示:
例如:
/*+ index(MSL XCL01000) */
谢谢你的宝贵意见。我当然更了解暗示的危险性和必要性。
https://stackoverflow.com/questions/28816385
复制相似问题