ORACLE hint命令用法说明
- 格式:doc
- 大小:40.00 KB
- 文档页数:5
常见OracleHINT的⽤法Hint概述基于代价的优化器是很聪明的,在绝⼤多数情况下它会选择正确的优化器,减轻了DBA的负担。
但有时它也聪明反被聪明误,选择了很差的执⾏计划,使某个语句的执⾏变得奇慢⽆⽐。
此时就需要DBA进⾏⼈为的⼲预,告诉优化器使⽤我们指定的存取路径或连接类型⽣成执⾏计划,从⽽使语句⾼效的运⾏。
例如,如果我们认为对于⼀个特定的语句,执⾏全表扫描要⽐执⾏索引扫描更有效,则我们就可以指⽰优化器使⽤全表扫描。
在Oracle 中,是通过为语句添加 Hints(提⽰)来实现⼲预优化器优化的⽬的。
不建议在代码中使⽤hint,在代码使⽤hint使得CBO⽆法根据实际的数据状态选择正确的执⾏计划。
毕竟数据是不断变化的, 10g以后的CBO也越来越完善,⼤多数情况下我们该让Oracle⾃⾏决定采⽤什么执⾏计划。
Oracle Hints是⼀种机制,⽤来告诉优化器按照我们的告诉它的⽅式⽣成执⾏计划。
我们可以⽤Oracle Hints来实现:1) 使⽤的优化器的类型2) 基于代价的优化器的优化⽬标,是all_rows还是first_rows。
3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利⽤rowid。
4) 表之间的连接类型5) 表之间的连接顺序6) 语句的并⾏程度除了”RULE”提⽰外,⼀旦使⽤的别的提⽰,语句就会⾃动的改为使⽤CBO优化器,此时如果你的数据字典中没有统计数据,就会使⽤缺省的统计数据。
所以建议⼤家如果使⽤CBO或Hints提⽰,则最好对表和索引进⾏定期的分析。
如何使⽤Hints:Hints只应⽤在它们所在sql语句块(statement block,由select、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]]...注解:1) DELETE、INSERT、SELECT和UPDATE是标识⼀个语句块开始的关键字,包含提⽰的注释只能出现在这些关键字的后⾯,否则提⽰⽆效。
写HINT目的手工指定SQL语句的执行计划hints是oracle提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。
我们可以用hints来实现:1) 使用的优化器的类型2) 基于代价的优化器的优化目标,是all_rows还是first_rows。
3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用rowid。
4) 表之间的连接类型5) 表之间的连接顺序6) 语句的并行程度2、HINT可以基于以下规则产生作用表连接的顺序、表连接的方法、访问路径、并行度3、HINT应用范围dml语句查询语句4、语法{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */or{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...如果语(句)法不对,则ORACLE会自动忽略所写的HINT,不报错1. /*+ALL_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.例如:SELECT /*+ALL_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHEREEMP_NO='SCOTT';2. /*+FIRST_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.例如:SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHEREEMP_NO='SCOTT';3. /*+CHOOSE*/表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;例如:SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHEREEMP_NO='SCOTT';4. /*+RULE*/表明对语句块选择基于规则的优化方法.例如:SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHEREEMP_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 WHEREROWID>='AAAAAAAAAAAAAA'AND EMP_NO='SCOTT';7. /*+CLUSTER(TABLE)*/提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.例如:SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMSWHERE 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 WHEREDPT_NO='SCOTT';10. /*+INDEX_COMBINE*/为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.例如:SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMSWHERE SAL<5000000 AND HIREDATE11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/提示明确命令优化器使用索引作为访问路径.例如:SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATEFROM BSEMPMS WHERE SAL<60000;12. /*+INDEX_DESC(TABLE INDEX_NAME)*/表明对表选择索引降序的扫描方法.例如:SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHEREDPT_NO='SCOTT';13. /*+INDEX_FFS(TABLE INDEX_NAME)*/对指定的表执行快速全索引扫描,而不是全表扫描的办法.例如:SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHEREDPT_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 WHEREA.DPT_NO=V.DPT_NOAND 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 ;31. NO_INDEX: 指定不使用哪些索引/*+ NO_INDEX ( table [index [index]...] ) */select /*+ no_index(emp ind_emp_sal ind_emp_deptno)*/ * from emp wheredeptno=200 and sal>300;32. parallelselect /*+ parallel(emp,4)*/ * from emp where deptno=200 and sal>300;另:每个SELECT/INSERT/UPDATE/DELETE命令后只能有一个/*+ */,但提示内容可以有多个,可以用逗号分开,空格也可以。
oracle hint 使用方式Oracle Hint 的使用方式Oracle Hint 是数据库优化技术,允许开发者向查询器提供建议,以优化执行计划。
这些提示可以提高查询性能,但必须谨慎使用,因为不恰当的提示可能导致性能下降。
类型Oracle Hint 主要分为两类:成本提示 (Cost Hints):建议优化器预期操作的成本。
执行计划提示 (Execution Plan Hints):直接指定查询器应如何执行查询。
使用要使用 Oracle Hint,必须将其添加到查询语句中。
有两种语法:行提示 (Inline Hints):直接在查询语句中添加 Hint,例如:```sqlSELECT FROM table_name WHERE column_name = value /+ INDEX(table_name column_name) /;```块提示 (Block Hints):将 Hint 放在单独的提示块中,例如:```sql/+ INDEX(table_name column_name) /SELECT FROMtable_name WHERE column_name = value;```常用提示一些常用的 Oracle Hint 包括:INDEX():强制优化器使用指定的索引。
NO_INDEX():强制优化器不使用指定的索引。
FIRST_ROWS():优化查询以快速检索前 N 行。
ALL_ROWS():优化查询以检索所有行。
USE_NL():强制优化器使用 Nested Loops 优化器。
USE_HASH():强制优化器使用哈希表优化器。
注意事项使用 Oracle Hint 时要注意以下事项:仅在必要时使用 Hint:不恰当的 Hint 会降低性能。
测试 Hint 的影响:在生产环境中应用 Hint 之前,务必测试其影响。
使用最新的优化器统计:过期或不准确的统计信息可能会导致Hint 无效。
OracleHint(提⽰)和INDEX(索引)的⼀些忠告Oracle的hint种类繁多,⼤致可以分为下⾯⼏类:
优化⽅式和⽬标:如RULE、CHOOSE、FIRST_ROWS、ALL_ROWS等。
访问路径:如INDEX、FULL、CLUSTER、INDEX_FFS等。
查询转换:如MERGE、USE_CONCAT、NO_EXPAND等。
连接顺序:如LEADING、ORDERED、STAR等。
连接操作:如USE_NL、USE_HASH、USE_MERGE等。
并⾏执⾏:如PARALLE、NOPARALLEL、PARALLEL_INDEX等。
其他类型;如APPEND、UNNEST、CACHE等。
INDEX只是Hint的⼀类。
Hint是把双刃剑,甚⾄是颗炸弹。
对于DB设计者、SQL制作者、DBA在优化SQL时,存在以下效率的⾼低:
追加约束条件 > 调整SQL逻辑 > 设计INDEX > 加⼊Hint
⽽且越后⾯的风险也越⼤。
因为开发环境、测试环境、最终客户环境的数据量、数据库版本、硬件等等总会有不同;
⽽Hint是强制执⾏的(⾃动忽略错误Hint语句),
就会产⽣在某处⾼效的Hint,在另⼀处却⾮常耗费资源。
如果不是可以在最终客户环境上操作的DBA,最好不要写Hint,
只要做好INDEX,
Oracle的⾃动优化⼀定会⽤。
oraclehints用法总结Oracle Hints是Oracle数据库中的一种特殊语法,用于向查询优化器提供指导信息,以改善查询执行计划的选择和性能。
Hints的基本语法如下:```SELECT /*+ hint */ column1, column2, ...FROM tableWHERE condition;```Hints是作为注释添加到SQL语句的SELECT子句的开始部分,以/*+ ... */的格式出现。
注释中的hint会告诉优化器如何在查询生成执行计划时处理查询。
Hints主要用于以下几个方面的优化:1. Optimizer Mode通过Optimizer Mode选项可以改变优化器的行为。
在SQL语句中使用ALL_ROWS,FIRST_ROWS,CHOOSE或RULE来改变优化器的模式。
例如:```SELECT /*+ ALL_ROWS */ column1, column2, ...FROM tableWHERE condition;```2. Join Order通过使用Join Order来改变查询的连接顺序,从而控制查询计划中连接操作的执行顺序。
例如:```SELECT /*+ ORDERED */ column1, column2 ...FROM table1, table2WHERE table1.column = table2.column;```3. Join Method通过使用Join Method来指定连接操作使用的算法。
可以使用HASH_JOIN,MERGE_JOIN或NL_JOIN来改变连接方法。
例如:```SELECT /*+ USE_HASH (table1)*/ column1, column2 ...FROM table1, table2WHERE table1.column = table2.column;```4. Access Method通过使用Access Method来指定访问表的方法,例如FULL,INDEX或CLUSTER。
oracle hint 使用方式Oracle Hint 的使用方式Oracle Hint 是一种机制,允许开发人员向数据库管理系统(DBMS) 提供有关如何执行查询或 DML 语句的建议。
它们可以通过提高查询性能、优化资源利用和确保数据完整性来对应用程序产生重大影响。
类型有两种类型的 Hint:静态 Hint:这些 Hint 在 SQL 语句中作为注释硬编码。
它们在编译时被 DBMS 评估,并用于在执行期间指导查询计划。
动态 Hint:这些 Hint 在运行时通过使用 DBMS_HINT 包的程序接口进行设置。
它们允许应用程序根据特定条件或用户输入动态调整查询行为。
语法静态 Hint 的语法如下:```/+ hint_name(hint_value) /SELECT ...FROM ...```其中:hint_name 是 Hint 的名称,例如 INDEX 或 FULL。
hint_value 是 Hint 的值,例如表名或索引名。
动态 Hint 的语法如下:```DBMS_HINT.SET_HINT(hint_name, hint_value);```其中:hint_name 是 Hint 的名称,例如 ACCESS。
hint_value 是 Hint 的值,例如 ROWID。
常用 Hint一些常用的 Hint 包括:INDEX(table_name, index_name):指示 DBMS 使用指定的索引进行表访问。
NO_INDEX(table_name):指示 DBMS 不要为表访问使用任何索引。
USE_HASH(table_name):指示 DBMS 使用哈希连接来连接表。
USE_NL(table_name):指示 DBMS 使用嵌套循环连接来连接表。
FIRST_ROWS(n):指示 DBMS 仅返回查询的前 n 行。
ALL_ROWS:指示 DBMS 返回查询的所有行。
示例示例 1:使用静态 Hint 优化索引使用```/+ INDEX(emp, idx_emp_dept) /SELECTFROM empWHERE deptno = 10;```此 Hint 指示 DBMS 在访问 emp 表时使用 idx_emp_dept 索引。
Oraclehint详解转⾃:⼀、提⽰(Hint)概述1为什么引⼊Hint?Hint是Oracle数据库中很有特⾊的⼀个功能,是很多DBA优化中经常采⽤的⼀个⼿段。
那为什么Oracle会考虑引⼊优化器呢?基于代价的优化器是很聪明的,在绝⼤多数情况下它会选择正确的优化器,减轻DBA的负担。
但有时它也聪明反被聪明误,选择了很差的执⾏计划,使某个语句的执⾏变得奇慢⽆⽐。
此时就需要DBA进⾏⼈为的⼲预,告诉优化器使⽤指定的存取路径或连接类型⽣成执⾏计划,从⽽使语句⾼效地运⾏。
Hint就是Oracle提供的⼀种机制,⽤来告诉优化器按照告诉它的⽅式⽣成执⾏计划。
2不要过分依赖Hint当遇到SQL执⾏计划不好的情况,应优先考虑统计信息等问题,⽽不是直接加Hint了事。
如果统计信息⽆误,应该考虑物理结构是否合理,即没有合适的索引。
只有在最后仍然不能SQL按优化的执⾏计划执⾏时,才考虑Hint。
毕竟使⽤Hint,需要应⽤系统修改代码,Hint只能解决⼀条SQL的问题,并且由于数据分布的变化或其他原因(如索引更名)等,会导致SQL再次出现性能问题。
3Hint的弊端Hint是⽐较"暴⼒"的⼀种解决⽅式,不是很优雅。
需要开发⼈员⼿⼯修改代码。
Hint不会去适应新的变化。
⽐如数据结构、数据规模发⽣了重⼤变化,但使⽤Hint的语句是感知变化并产⽣更优的执⾏计划。
Hint随着数据库版本的变化,可能会有⼀些差异、甚⾄废弃的情况。
此时,语句本⾝是⽆感知的,必须⼈⼯测试并修正。
4Hint与注释关系提⽰是Oracle为了不破坏和其他数据库引擎之间对SQL语句的兼容性⽽提供的⼀种扩展功能。
Oracle决定把提⽰作为⼀种特殊的注释来添加。
它的特殊性表现在提⽰必须紧跟着DELETE、INSERT、UPDATE或MERGE关键字。
换句话说,提⽰不能像普通注释那样在SQL语句中随处添加。
且在注释分隔符之后的第⼀个字符必须是加号。
OracleHint⽤法正确的语法是:select /*+ index(x idx_t) */ * from t x where x.object_id=123/*+ */ 和注释很像,⽐注释多了⼀个“+”,这就是Hint上⾯这个hint的意思是让Oracle执⾏这个SQL时强制⾛索引。
如果hint的语法有错误,Oracle是不会报错,只是把/* */⾥的内容当做注释⽽已。
不合理使⽤Hint的危害:由于表中的数据是会变化,⼀般不能在程序中的sql⾥⽤Hint,假如像上⾯的Hint⼀样强制⾛索引。
万⼀某⼀天object_id=123的返回结果占了全表的50%以上,这时候⾛索引会⽐全表扫描慢。
所以不该强制所有情况都⾛索引。
Hint⼀般⽤于⼀次执⾏,⽐如做数据抽取。
⽽且⼀般Oracle在99%的情况下会判断正确是否该⾛索引,不需要我们去指定。
Hint只是为了应付1%的情况下。
Append的使⽤:append是另⼀种Hint,⼀般⽤法:insert /*+ append */ into b select * from a;这种insert⽐普通的insert会快⼀些,但代价也⼤。
1、当表中的数据被delete以后,表空间会留下空隙,下次insert时会去填补空隙。
但是append的insert不会去找空隙,⽽且直接追加到新的空间⾥。
如果⼀直⽤append,会使表空间越来越⼤。
2、这点是⽐较致命的,就是⽤append的时候,会把整个表锁住,别的⽤户即使insert别的数据也要被阻塞。
所以⽣产环境肯定不能⽤append,append也⼀般⽤于数据抽取⼀类的⼯作。
其实⼤多数情况下,⽤append提⾼不了多少效率。
因为append之所以快的原因,是因为减少了⽇志产⽣。
只有以下场景append会减少⽇志产⽣:1、⾮归档模式下2、归档模式下,表的状态是nologging⾸先⾮归档状态⼀般是不可能的,稍微重要点的系统都必须开归档。
在sql语句优化过程中,我们经常会用到hint,现总结一下在sql优化过程中常见oracle hint的用法: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,bsdptmswhere 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 wheresex=''m'';9. /*+index_asc(table index_name)*/(同/*+index(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 bsempmswhere sal<5000000 and hiredate<sysdate;11. /*+index_join(table index_name)*/提示明确命令优化器使用索引作为访问路径.例如:select /*+index_join(bsempms sal_hmi hiredate_bmi)*/ sal,hiredatefrom 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,...*/ (同/*+index_combine*/)提示明确进行执行规划的选择,将几个单列索引的扫描合起来.例如: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_noand 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)*/ (同/*+ordered*/)将指定的表作为连接次序中的首表.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 ;。
在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: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 BSEMPMSWHERE SAL<5000000 AND HIREDA TE<SYSDATE;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_CONCA T*/ * 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,A VG(SAL) AS A VG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NOAND A.SAL>V.A VG_SAL;20. /*+NO_MERGE(TABLE)*/对于有可合并的视图不再合并.例如:SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,A VG(SAL) AS A VG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.A VG_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 ;。