Hints详解

Hints详解在向大家详细介绍 OracleHints 之前 首先让大家了解下 OracleHints 是什么 然后全面介绍 OracleHints 希望对大家有用 基于代价的优化器是很聪明的 在绝大多数情况下它会选择正确的优化器 减轻了 DBA 的负担 但有时它也聪明反被聪明误 选择了很差的执行计划 使某个语句的执行变得奇慢无比 此时就需要 DBA 进行人为的干预 告诉优化器使用我们指定的存取路径或连接类型生成执行计划 从

在向大家详细介绍Oracle Hints之前,首先让大家了解下Oracle Hints是什么,然后全面介绍Oracle Hints,希望对大家有用。基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。

此时就需要DBA进行人为的干预,告诉优化器使用我们指定的存取路径或连接类型生成执行计划,从而使语句高效的运行。例如,如果我们认为对于一个特定的语句,执行全表扫描要比执行索引扫描更有效,则我们就可以指示优化器使用全表扫描。在Oracle中,是通过为语句添加 Hints(提示)来实现干预优化器优化的目的。

除了”RULE”提示外,一旦使用的别的提示,语句就会自动的改为使用CBO优化器,此时如果你的数据字典中没有统计数据,就会使用缺省的统计数据。所以建议大家如果使用CBO或Hints提示,则最好对表和索引进行定期的分析。

如何使用Hints:

Hints只应用在它们所在sql语句块(statement block,由select、insert、update、delete关键字标识)上,对其它SQL语句或语句的其它部分没有影响。如:对于使用union操作的2个 sql语句,如果只在一个sql语句上有Hints,则该Hints不会影响另一个sql语句。

我们可以使用注释(comment)来为一个语句添加Hints,一个语句块只能有一个注释,而且注释只能放在SELECT, UPDATE, or DELETE关键字的后面

使用Oracle Hints的语法:

{DELETE|INSERT|SELECT|UPDATE} /+ hint [text] [hint[text]]… /

or

{DELETE|INSERT|SELECT|UPDATE} –+ hint [text] [hint[text]]…

如果你没有正确的指定Hints,Oracle将忽略该Hints,并且不会给出任何错误。

  1. /+ALL_ROWS/
      表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.
      例如:
      SELECT /+ALL+_ROWS/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;
      2. /+FIRST_ROWS/
      表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.
      例如:
      SELECT /+FIRST_ROWS/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;
      3. /+CHOOSE/
      表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;
      表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;
      例如:
      SELECT /+CHOOSE/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;
      4. /+RULE/
      表明对语句块选择基于规则的优化方法.
      例如:
      SELECT /+ RULE / EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO=’SCOTT’;
      5. /+FULL(TABLE)/
      表明对表选择全局扫描的方法.
      例如:
      SELECT /+FULL(A)/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO=’SCOTT’;
      6. /+ROWID(TABLE)/
      提示明确表明对指定表根据ROWID进行访问.
      例如:
      SELECT /+ROWID(BSEMPMS)/ * FROM BSEMPMS WHERE ROWID>=’AAAAAAAAAAAAAA’
      AND EMP_NO=’SCOTT’;
      7. /+CLUSTER(TABLE)/
      提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.
      例如:
      SELECT /+CLUSTER / BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
      WHERE DPT_NO=’TEC304’ AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      8. /+INDEX(TABLE INDEX_NAME)/
      表明对表选择索引的扫描方法.
      例如:
      SELECT /+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS / FROM BSEMPMS WHERE SEX=’M’;
      9. /+INDEX_ASC(TABLE INDEX_NAME)/
      表明对表选择索引升序的扫描方法.
      例如:
      SELECT /+INDEX_ASC(BSEMPMS PK_BSEMPMS) / FROM BSEMPMS WHERE DPT_NO=’SCOTT’;
      10. /+INDEX_COMBINE/
      为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.
      例如:
      SELECT /+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)/ * FROM BSEMPMS
      WHERE SAL< AND HIREDATE
      11. /+INDEX_JOIN(TABLE INDEX_NAME)/
      提示明确命令优化器使用索引作为访问路径.
      例如:
      SELECT /+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)/ SAL,HIREDATE
      FROM BSEMPMS WHERE SAL<60000;
      12. /+INDEX_DESC(TABLE INDEX_NAME)/
      表明对表选择索引降序的扫描方法.
      例如:
      SELECT /+INDEX_DESC(BSEMPMS PK_BSEMPMS) / FROM BSEMPMS WHERE DPT_NO=’SCOTT’;
      13. /+INDEX_FFS(TABLE INDEX_NAME)/
      对指定的表执行快速全索引扫描,而不是全表扫描的办法.
      例如:
      SELECT /+INDEX_FFS(BSEMPMS IN_EMPNAM)/ * FROM BSEMPMS WHERE DPT_NO=’TEC305’;
      14. /+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,…/
      提示明确进行执行规划的选择,将几个单列索引的扫描合起来.
      例如:
      SELECT /+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)/ * FROM BSEMPMS WHERE EMP_NO=’SCOTT’ AND DPT_NO=’TDC306’;
      15. /+USE_CONCAT/
      对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.
      例如:
      SELECT /+USE_CONCAT/ * FROM BSEMPMS WHERE DPT_NO=’TDC506’ AND SEX=’M’;
      16. /+NO_EXPAND/
      对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.
      例如:
      SELECT /+NO_EXPAND/ * FROM BSEMPMS WHERE DPT_NO=’TDC506’ AND SEX=’M’;
      17. /+NOWRITE/
      禁止对查询块的查询重写操作.
      18. /+REWRITE/
      可以将视图作为参数.
      19. /+MERGE(TABLE)/
      能够对视图的各个查询进行相应的合并.
      例如:
      SELECT /+MERGE(V) / A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
      ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO
      AND A.SAL>V.AVG_SAL;
      20. /+NO_MERGE(TABLE)/
      对于有可合并的视图不再合并.
      例如:
      SELECT /+NO_MERGE(V) / A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;
      21. /+ORDERED/
      根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.
      例如:
      SELECT /+ORDERED/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;
      22. /+USE_NL(TABLE)/
      将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.
      例如:
      SELECT /+ORDERED USE_NL(BSEMPMS)/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      23. /+USE_MERGE(TABLE)/
      将指定的表与其他行源通过合并排序连接方式连接起来.
      例如:
      SELECT /+USE_MERGE(BSEMPMS,BSDPTMS)/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      24. /+USE_HASH(TABLE)/
      将指定的表与其他行源通过哈希连接方式连接起来.
      例如:
      SELECT /+USE_HASH(BSEMPMS,BSDPTMS)/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      25. /+DRIVING_SITE(TABLE)/
      强制与ORACLE所选择的位置不同的表进行查询执行.
      例如:
      SELECT /+DRIVING_SITE(DEPT)/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;
      26. /+LEADING(TABLE)/
      将指定的表作为连接次序中的首表.
      27. /+CACHE(TABLE)/
      当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
      例如:
      SELECT /+FULL(BSEMPMS) CAHE(BSEMPMS) / EMP_NAM FROM BSEMPMS;
      28. /+NOCACHE(TABLE)/
      当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
      例如:
      SELECT /+FULL(BSEMPMS) NOCAHE(BSEMPMS) / EMP_NAM FROM BSEMPMS;
      29. /+APPEND/
      直接插入到表的最后,可以提高速度.
      insert /+append/ into test1 select * from test4 ;
      30. /+NOAPPEND/
      通过在插入语句生存期内停止并行模式来启动常规插入.
      insert /+noappend/ into test1 select * from test4 ;





















































































































    1. NO_INDEX: 指定不使用哪些索引

    /+ NO_INDEX ( table [index [index]…] ) /

    select /+ no_index(emp ind_emp_sal ind_emp_deptno)/ * from emp where deptno=200 and sal>300;

    1. parallel

    select /+ parallel(emp,4)/ * from emp where deptno=200 and sal>300;

    另:每个SELECT/INSERT/UPDATE/DELETE命令后只能有一个/+ /,但提示内容可以有多个,可以用逗号分开,空格也可以。

    如:/+ ordered index() use_nl() /


类似如下的一条语句:insert into xxxx select /+parallel(a) / * from xxx a;数据量大约在75G左右,这位兄弟从上午跑到下午还没跑完,过来问我咋回事,说平常2hrs能跑完的东西跑了好几个小时还撒动静。查看系统性能也比较 正常,cpu,io都不繁忙,平均READ速度在80M/s左右(勉强凑合),但平均写速度只有10M不到。等待事件里面大量的‘ ‘PX Deq Credit: send blkd’,这里能看出并行出了问题,从而最后得知是并行用法有问题,修改之后20分钟完成了该操作。正确的做法应该是:
alter session enable dml parallel;

insert /+parallel(xxxx,4) / into xxxx select /+parallel(a) / * from xxx a;

因为oracle默认并不会打开PDML,对DML语句必须手工启用。 另外不得不说的是,并行不是一个可扩展的特性,只有在数据仓库或作为DBA等少数人的工具在批量数据操作时利于充分利用资源,而在OLTP环境下使用并行 需要非常谨慎。事实上PDML还是有比较多的限制的,例如不支持触发器,引用约束,高级复制和分布式事务等特性,同时也会带来额外的空间占用,PDDL同 样是如此。有关Parallel excution可参考官方文档,在Thomas Kyte的新书《Expert Oracle Database architecture》也有精辟的讲述。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210295.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午7:53
下一篇 2026年3月19日 上午7:53


相关推荐

  • Mybatis中javaType和jdbcType对应关系

    Mybatis中javaType和jdbcType对应关系

    2021年9月7日
    80
  • 中通笔试题:翻转字符串,例如abcd打印出dcba

    中通笔试题:翻转字符串,例如abcd打印出dcba翻转一个字符,比如:abcd—&gt;dcbapublic class 倒转字符串 { public static void main(String[] args) { System.out.print("翻转后字符串:" ); String str = "abcde"; for (int i = str.length()-1; i&gt;=0; i–) { S…

    2022年6月13日
    31
  • php编程json,php字符转json对象的方法

    php编程json,php字符转json对象的方法php 字符转 json 对象的方法发布时间 2020 07 0810 36 42 来源 亿速云阅读 76 作者 Leah 这期内容当中小编将会给大家带来有关 php 字符转 json 对象的方法 文章内容丰富且以专业的角度为大家分析和叙述 阅读完这篇文章希望大家可以有所收获 php 字符转 json 对象的方法 首先新建一个空的 php 文件 然后定义一个数组 并调用 json encode 方法将数组编码为 json 格式的

    2026年3月17日
    1
  • petri网基本概念

    petri网基本概念Petri 网是对离散并行系统的数学表示 Petri 网既有严格的数学表述方式 也有直观的图形表达方式 既有丰富的系统描述手段和系统行为分析技术 Petri 网用于描述和分析系统中的控制流和信息流 尤其是那些有异步和并发活动的系统 经典的 Petri 网是简单的过程模型 由两种节点 库所和变迁 有向弧 以及令牌等元素组成的 结构 1 Petri 网的元素 库所 Place 圆形节点变迁 Transition 方形节点有向弧 Connection 是库所和变迁之间的有向弧令牌 Token

    2026年3月17日
    0
  • 内容大合集_十三大内容

    内容大合集_十三大内容文顶顶大神http://www.cnblogs.com/wendingding/p/3805088.html碎片知识大合集http://www.cnblogs.com/wujy/p/457161

    2022年8月5日
    8
  • NOIP2011 观光公交

    NOIP2011 观光公交话说 我终于 AC 了这个题这是一个贪心 说实话开始做的时候 完全没看出来 QAQ 可能有人说这是个 dp 但这真不是 dalao 请无视 这真的只是个贪心 首先对于每个点当然是能走就走 不能走就等待 这是无法控制的 所以只考虑氮气加速器加在哪里可以使时间总和尽量少 所以如果选择加速 可能会使后面等待的时间更长 或者更短 对后面都会有影响 但是沿着一条边加速会影响后面的所

    2026年3月17日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号