何时在 oracle 查询中使用提示 [重复]
Posted
技术标签:
【中文标题】何时在 oracle 查询中使用提示 [重复]【英文标题】:When to use hints in oracle query [duplicate] 【发布时间】:2017-07-12 05:45:08 【问题描述】:我浏览了网络上的一些文档,并且大多不鼓励使用提示。我对此仍有疑问。特别是当数百个不同的客户使用相同的查询时,提示在生产中是否真正有用。
只有当我们知道表中存在的记录数时,提示才有用吗?我在查询中使用 leading,当数据非常大时它会提供更快的结果,但当获取的记录较少时性能不是那么好。
David 的 answer 非常好,但如果有人能更详细地澄清这一点,我将不胜感激。
【问题讨论】:
基本思想是优化器相当聪明,并使用有关您的表的统计信息来决定执行哪种查询策略。如果您使用提示,例如强制索引,然后当您的数据更改时,执行的计划可能不是最好的。话虽如此,在某些情况下使用提示是合适的,但这种情况比较少见。 这个没有实质性的文章和很多例子就无法回答,这里真的合适吗? 不鼓励发布到 SO 的问题只能通过意见来回答。查找作者展示其所有作品并提供性能统计数据的书籍、博客条目等,以证明一种方法更适合给定。 【参考方案1】:大多数提示都是将我们的意图传达给优化器的一种方式。例如,您提到的leading
提示意味着按此顺序连接表。为什么这是必要的?通常是因为最优连接顺序不明显,查询写得不好或者数据库统计不准确。
因此,leading
等提示的一种用途是找出最佳执行路径,然后找出数据库在没有提示的情况下不选择该计划的原因。收集新的统计数据能解决问题吗?重写 FROM 子句能解决问题吗?如果是这样,我们可以删除提示并部署裸 SQL。
有时我们无法解决这个难题,必须将提示保留在生产环境中。然而,这应该是一个罕见的例外。多年来,Oracle 有很多非常聪明的人致力于基于成本的优化器,因此它的决策通常比我们的要好。
但在制作中我们不会眨眼看到其他提示。 append
通常对于调整批量插入至关重要。 driving_site
在调优分布式查询方面非常重要。
相反,其他提示几乎总是被滥用。是的parallel
,我说的是你。盲目地输入 /*+ parallel (t23, 16) */
可能不会使您的查询运行速度快 16 倍,而且通常会导致检索速度比单线程执行慢。
因此,简而言之,对于何时应该使用提示没有普遍适用的建议。关键是:
-
了解数据库的工作原理,尤其是基于成本的优化器的工作原理;
了解每个提示的作用;
在适当的调优环境中使用生产等效数据测试提示查询。
显然,最好的起点是the Oracle documentation。但是,如果您想花一些钱,Jonathan Lewis 关于the Cost-Based Optimizer 的书是您可以做出的最佳投资。
【讨论】:
【参考方案2】:我不能只是改写,所以我将它粘贴在这里 (这是对“何时不使用提示”的简要说明,我已加入书签):
总之,不要使用提示
对hint的作用知之甚少,当然不限于(ab)使用hint;
您还没有研究不良 SQL 代码的根本原因,因此还没有利用 DBA 在调整数据库方面的丰富专业知识和经验;
您的统计信息已过期,您可以更频繁地刷新统计信息,甚至可以将统计信息修复为具有代表性的状态;
您不打算定期检查语句中提示的正确性,这意味着,当统计数据发生变化时,提示可能严重不足;
无论如何,您都无意记录提示的使用。
来源链接here。
我可以总结为:使用提示不仅是最后的手段,而且对问题的根本原因缺乏了解。 CBO(基于成本的优化器)做得很好,如果你只是确保它的一些基础知识。其中包括:
-
最新统计
1.1。指数统计
1.2.表统计
1.3.直方图
正确的
JOIN
条件和INDEX
利用率
正确的数据库设置
这里的这篇文章值得一读: Top 10 Reasons for poor Oracle performance
由 Donald Burleson 先生提供。
干杯
【讨论】:
【参考方案3】:一般来说,提示应该只在例外情况下使用,我知道以下情况下它们是有意义的:
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 documentation:
CHANGE_DUPKEY_ERROR_INDEX
、IGNORE_ROW_ON_DUPKEY_INDEX
和RETRY_ON_ROW_CHANGE
提示不同于其他提示,因为它们有一个 语义效应。 “提示”中解释的一般哲学并不 申请这三个提示。
【讨论】:
以上是关于何时在 oracle 查询中使用提示 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
向oracle数据库中插入数据时,先判断插入数据是不是重复,如果重复,通过sql提示重新输入,否则直接插入
oracle如何查询重复数据然后全部显示,举例:一份Excel中有100条数据,只有10条不同,我一个个