我浏览了网上的一些文档,并且大多不鼓励使用提示。我对此仍有疑问。当数百个不同的客户使用相同的查询时,提示在生产中是否真的有用。
只有当我们知道表中存在的记录数时,提示才有用吗?我在查询中使用前导,当数据非常大时它会提供更快的结果,但是当获取的记录较少时性能不是那么好。
大卫的这个答案非常好,但如果有人更详细地澄清这一点,我将不胜感激。
我浏览了网上的一些文档,并且大多不鼓励使用提示。我对此仍有疑问。当数百个不同的客户使用相同的查询时,提示在生产中是否真的有用。
只有当我们知道表中存在的记录数时,提示才有用吗?我在查询中使用前导,当数据非常大时它会提供更快的结果,但是当获取的记录较少时性能不是那么好。
大卫的这个答案非常好,但如果有人更详细地澄清这一点,我将不胜感激。
大多数提示都是将我们的意图传达给优化器的一种方式。例如,leading
您提到的提示意味着按此顺序连接表。为什么这是必要的?往往是因为最优连接顺序不明显,查询写得不好或者数据库统计不准确。
因此,提示的一种用途leading
是找出最佳执行路径,然后找出为什么数据库在没有提示的情况下不选择该计划。收集新的统计数据能解决问题吗?重写 FROM 子句能解决问题吗?如果是这样,我们可以删除提示并部署裸 SQL。
有时我们无法解决这个难题,必须在生产中保留提示。然而,这应该是一个罕见的例外。多年来,Oracle 有很多非常聪明的人致力于基于成本的优化器,因此它的决策通常比我们的要好。
但是在生产中我们不会眨眼看到其他提示。append
通常对于调整批量插入至关重要。driving_site
对于调优分布式查询至关重要。
相反,其他提示几乎总是被滥用。是parallel
的,我在说你。盲目地放置/*+ parallel (t23, 16) */
可能不会使您的查询运行速度快 16 倍,并且经常会导致比单线程执行更慢的检索。
因此,简而言之,对于何时应该使用提示没有普遍适用的建议。关键是:
显然,最好的起点是Oracle 文档。但是,如果您想花一些钱,乔纳森·刘易斯(Jonathan Lewis)关于基于成本的优化器的书是您可以做出的最佳投资。
我不能只是改写它,所以我将它粘贴在这里(这是对"When Not To Use Hints"的简要解释,我已添加书签):
总之,不要使用提示
对提示的作用知之甚少,当然不限于提示的(ab)使用;
您还没有研究糟糕的 SQL 代码的根本原因,因此还没有利用 DBA 在调整数据库方面的丰富专业知识和经验;
您的统计数据已过时,您可以更频繁地刷新统计数据,甚至可以将统计数据修复为具有代表性的状态;
您不打算定期检查您的陈述中提示的正确性,这意味着,当统计数据发生变化时,提示可能会严重不足;
无论如何,您无意记录提示的使用。
源链接在这里。
我可以总结为:使用提示不仅是最后的手段,而且对问题的根本原因缺乏了解。CBO(基于成本的优化器)做得很好,如果你只是确保它的一些基础知识。其中包括:
JOIN
的条件和INDEX
使用这里的这篇文章值得一读: Oracle 性能不佳的 10 大原因
由唐纳德·伯勒森先生(Donald Burleson)先生提出。
干杯
一般来说,提示应该只在例外情况下使用,我知道以下情况是有意义的:
Oracle 错误的解决方法
示例:有一次 SELECT 语句出现错误ORA-01795: maximum expression number in list - 1000
,尽管查询根本不包含IN表达式。
问题是:查询表包含超过 1000 个(子)分区,Oracle 对我的查询进行了转换。使用(未记录的)提示NO_EXPAND_TABLE
解决了这个问题。
暂存时的 Datewarehouse 应用程序
在暂存时,您可以对表/索引统计信息不知道的数据进行重大更改,因为默认情况下每周仅收集一次统计信息。如果您知道您的数据结构,那么提示可能会很有用,因为它们比DBMS_STATS.GATHER_TABLE_STATS(...)
在您的操作之间一直手动运行要快。另一方面,您DBMS_STATS.GATHER_TABLE_STATS()
甚至可以运行单列,这可能是更好的方法。
在线应用升级提示
来自Oracle 文档:
、
CHANGE_DUPKEY_ERROR_INDEX
和提示IGNORE_ROW_ON_DUPKEY_INDEX
与RETRY_ON_ROW_CHANGE
其他提示的不同之处在于它们具有语义效果。“提示”中解释的一般哲学不适用于这三个提示。