oracle hints用法总结
1、写 HINT 目的 手工指定 SQL 语句的执行计划
hints 是 oracle 提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。我们可以用 hints 来实现: 1) 使用的优化器的类型 2) 基于代价的优化器的优化目标,是 all_row s 还是 first_rows。 3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用 row id。 4) 表之间的连接类型 5) 表之间的连接顺序 6) 语句的并行程度 2、HINT 可以基于以下规则产生作用 表连接的顺 序、表连 接的方法 、访问路 径、并行 度 3、HINT 应用范围 dml 语句 查询语句 4、语法
2. /*+FIRST_ROWS*/ 表明对语句块选择基于开 销的优化方法, 并获得最佳响应时 间,使资源消耗 最小化. 例如: SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO ='SCOTT';
3. /*+CHOOSE*/ 表明如果数据字典中有访 问表的统计信息 ,将基于开销的优 化方法,并获得 最佳的吞吐量 ;如果数据字典 中没有访 问表的统计信息,将基 于规则开销的优化 方法;
{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */ or {DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...
如果语(句)法不对,则 ORA CLE 会自动忽略所写的 HINT,不报错 5、指定优化器模式的 HINT RUL E: 不管是否 有统计信 息,都将 采用基于 规则进行 优化; CHOOS E:只 要被访问 的数据中 有一个表 有统计信 息,就将 采用基于 代价的方 式进行优 化;
例如: 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';
14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/ 提示明确进行执行规划的 选择,将几个单 列索引的扫描合起 来. 例如: SELECT /*+INDEX_FFS(BSEMPMS IN_DP TNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO=' TDC306';
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';
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';
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<5000000 AND HIREDATE
/*+ AND_EQUAL ( table index index [index]Байду номын сангаас[index] [index] ) */
7、指定表 的连接顺 序 ORDERED: 按表出现的顺序进行连接
/*+ ORDERED */ select /*+ordered*/ emp.ename,dept.dname from dept,emp where emp.deptno=dept.deptno; select /*+ordered*/ emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;
7. /*+CLUSTER(TABLE)*/ 提示明确表明对指定表选 择簇扫描的访问方 法,它只对簇对 象有效. 例如: SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDP TMS.DPT_NO ;
8、指定表 的连接操 作 USE_NL: 按 nested loops 方式连接 --默认 hash join,获取所有数据的最快返回时间
select emp.ename,dept.dname from dept,emp where emp.deptno=dept.deptno;
--指定 emp 作为 inner table ,以获取最快的响应时间
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';
hints in Oracle
hints 是 oracle 提供的一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。我们可以用 hints 来实现: 1) 使用的优化器的类型 2) 基于代价的优化器的优化目标,是 all_row s 还是 first_rows。 3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用 row id。 4) 表之间的连接类型 5) 表之间的连接顺序 6) 语句的并行程度
select /*+ordered use_nl(emp) to get first row faster */ emp.ename,dept.dname from dept,emp where emp.deptno=dept.deptno; select /*+ordered use_nl(emp dept)*/ emp.ename,dept.dname from dept,emp where emp.deptno=dept.deptno;
FIRST_ ROW S:不 管是否有 统计信息 ,都将采 用基于代 价的方式 进行优化 ,其优化 目标是最 快响应时 间; A LL_ROWS :不管是 否有统计 信息,都 将采用基 于代价的 方式进行 优化,其 优化目标 是最大吞 吐量; 例子: 尽快地显示前 10 行记录 select /*+ first_rows(10) */ * from emp where deptno=10; 6、指定访问路径的 HINT FULL: 执行全表扫描 /*+ FULL ( table ) */ ROID: 根据 ROWID 进行扫描 /*+ ROWID ( table ) */ INDEX: 根据某个索引进行扫描 /*+ INDEX ( table [index [index]...] ) */ select /*+ index(emp ind_emp_sal)*/ * from emp where deptno=200 and sal>300; 如果写了多个,则 ORACLE 自动选择最优的哪个 select /*+ index(emp ind_emp_sal ind_emp_deptno)*/ * from emp where deptno=200 and sal>300; INDEX_JOIN: 如果所选的字段都是索引字段(是几个索引的),那么可以通过索引连接就可访问到数据,而不需要访问表的数据。 /*+ INDEX_JOIN ( table [index [index ...]] ) */ select /*+ index_join(emp ind_emp_sal ind_emp_deptno)*/ deptno,sal from emp where deptno=20; INDEX_FFS: 执行快速全索引扫描 /*+ INDEX_FFS ( table [index [index]...] ) */ select /*+ index_ffs(emp pk_emp)*/ count(*) from emp; 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; AND_EQUAL: 指定合并两个或以上索引检索的结果(交集),最多不能超过 5 个
Oracle Hint使用实例
例如:
select /*+index_join(bsempms sal_hmi hiredate_bmi)*/ sal,hiredate
from bsempms where sal<60000;
12. /*+index_desc(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)*/ (排序归并) 能够对视图的各个查询进行相应的合并.
hint用法
1. /*+ALL_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.2. /*+FIRST_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.3. /*+CHOOSE*/表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;4. /*+RULE*/表明对语句块选择基于规则的优化方法.5. /*+FULL(TABLE)*/表明对表选择全局扫描的方法.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)*/表明对表选择索引的扫描方法. 通常用于指定谓词列使用索引9. /*+INDEX_ASC(TABLE INDEX_NAME)*/表明对表选择索引升序的扫描方法.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)*/提示明确命令优化器使用索引作为访问路径. index_join通常用于小于1w行的连接例如:SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATEFROM BSEMPMS WHERE SAL<60000;12. /*+INDEX_DESC(TABLE INDEX_NAME)*/表明对表选择索引降序的扫描方法.13. /*+INDEX_FFS(TABLE INDEX_NAME)*/对指定的表执行快速全索引扫描,而不是全表扫描的办法.,只能用于not null列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 WHEREA.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;21. /*+ORDERED*/根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.22. /*+USE_NL(TABLE)*/将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.例如:SELECT /*+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,BSDPTMSWHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;24. /*+USE_HASH(TABLE)*/将指定的表与其他行源通过哈希连接方式连接起来.例如:SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMSWHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;25. /*+DRIVING_SITE(TABLE)*/强制与ORACLE所选择的位置不同的表进行查询执行.例如:SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMSWHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;26. /*+LEADING(TABLE)*/将指定的表作为连接次序中的首表.27. /*+CACHE(TABLE)*/当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端28. /*+NOCACHE(TABLE)*/当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端29. /*+APPEND*/直接插入到表的最后,可以提高速度.30. /*+NOAPPEND*/通过在插入语句生存期内停止并行模式来启动常规插入.ALL_ROWS AND_EQUALANTIJOIN APPENDBITMAP BUFFERBYPASS_RECURSIVE_CHECK BYPASS_UJVCCACHE CACHE_CBCACHE_TEMP_TABLE CARDINALITYCHOOSE CIV_GBCOLLECTIONS_GET_REFS CPU_COSTINGCUBE_GB CURSOR_SHARING_EXACTDEREF_NO_REWRITE DML_UPDATEDOMAIN_INDEX_NO_SORT DOMAIN_INDEX_SORTDRIVING_SITE DYNAMIC_SAMPLINGDYNAMIC_SAMPLING_EST_CDN EXPAND_GSET_TO_UNIONFACT FIRST_ROWSFORCE_SAMPLE_BLOCK FULLGBY_CONC_ROLLUP GLOBAL_TABLE_HINTSHASH HASH_AJHASH_SJ HWM_BROKEREDIGNORE_ON_CLAUSE IGNORE_WHERE_CLAUSEINDEX_ASC INDEX_COMBINEINDEX_DESC INDEX_FFSINDEX_JOIN INDEX_RRSINDEX_SS INDEX_SS_ASCINDEX_SS_DESC INLINELEADING LIKE_EXPANDLOCAL_INDEXES MATERIALIZEMERGE MERGE_AJMERGE_SJ MV_MERGENESTED_TABLE_GET_REFS NESTED_TABLE_SET_REFSNESTED_TABLE_SET_SETID NL_AJNL_SJ NO_ACCESSNO_BUFFER NO_EXPANDNO_EXPAND_GSET_TO_UNION NO_FACTNO_FILTERING NO_INDEXNO_MERGE NO_MONITORINGNO_ORDER_ROLLUPS NO_PRUNE_GSETSNO_PUSH_PRED NO_PUSH_SUBQNO_QKN_BUFF NO_SEMIJOINNO_STATS_GSETS NO_UNNESTNOAPPEND NOCACHENOCPU_COSTING NOPARALLELNOPARALLEL_INDEX NOREWRITEOR_EXPAND ORDEREDORDERED_PREDICATES OVERFLOW_NOMOVE PARALLEL PARALLEL_INDEXPIV_GB PIV_SSFPQ_DISTRIBUTE PQ_MAPPQ_NOMAP PUSH_PREDPUSH_SUBQ REMOTE_MAPPEDRESTORE_AS_INTERVALS REWRITERULE SA VE_AS_INTERV ALSSCN_ASCENDING SELECTIVITYSEMIJOIN SEMIJOIN_DRIVERSKIP_EXT_OPTIMIZER SQLLDRSTAR STAR_TRANSFORMA TION SWAP_JOIN_INPUTS SYS_DL_CURSORSYS_PARALLEL_TXN SYS_RID_ORDERTIV_GB TIV_SSFUNNEST USE_ANTIUSE_CONCAT USE_HASHUSE_MERGE USE_NLUSE_SEMI USE_TTT_FOR_GSETS Undocumented (under-documented) hints:BYPASS_RECURSIVE_CHECK BYPASS_UJVCCACHE_CB CACHE_TEMP_TABLECIV_GB COLLECTIONS_GET_REFS CUBE_GB CURSOR_SHARING_EXACT DEREF_NO_REWRITE DML_UPDATEDOMAIN_INDEX_NO_SORT DOMAIN_INDEX_SORT DYNAMIC_SAMPLING DYNAMIC_SAMPLING_EST_CDN EXPAND_GSET_TO_UNION FORCE_SAMPLE_BLOCKGBY_CONC_ROLLUP GLOBAL_TABLE_HINTSHWM_BROKERED IGNORE_ON_CLAUSEIGNORE_WHERE_CLAUSE INDEX_RRSINDEX_SS INDEX_SS_ASCINDEX_SS_DESC LIKE_EXPANDLOCAL_INDEXES MV_MERGENESTED_TABLE_GET_REFS NESTED_TABLE_SET_REFS NESTED_TABLE_SET_SETID NO_EXPAND_GSET_TO_UNION NO_FACT NO_FILTERINGNO_ORDER_ROLLUPS NO_PRUNE_GSETSNO_STATS_GSETS NO_UNNESTNOCPU_COSTING OVERFLOW_NOMOVEPIV_GB PIV_SSFPQ_MAP PQ_NOMAPREMOTE_MAPPED RESTORE_AS_INTERV ALSSA VE_AS_INTERVALS SCN_ASCENDINGSKIP_EXT_OPTIMIZER SQLLDRSYS_DL_CURSOR SYS_PARALLEL_TXNSYS_RID_ORDER TIV_GBTIV_SSF UNNESTUSE_TTT_FOR_GSETS。
oracle exists的用法
oracle exists的用法Oracle Exists 是一种常用的数据库查询语句,主要用于检查表或视图中是否存在特定的条件。
本文将详细介绍Oracle Exists 的用法以及实际应用场景,并给出一些使用注意事项。
1.Oracle Exists 简介Oracle Exists 语句用于判断在指定的表或视图中,是否存在满足条件的记录。
如果存在满足条件的记录,则查询返回true,否则返回false。
Exists 语句通常与子查询一起使用,以便在父查询中根据子查询的结果来过滤数据。
2.Oracle Exists 用法详解Oracle Exists 语句的基本语法如下:```SELECT column1, column2, ...FROM table_nameWHERE EXISTS (subquery);```其中,column1、column2等表示要查询的表或视图中的列名,table_name 表示要查询的表或视图的名称,subquery 表示子查询。
例如,假设我们有一个员工表(employees),其中包括员工编号(id)、姓名(name)和部门编号(department_id)等列。
我们可以使用如下语句检查是否存在部门编号为10的员工:```sqlSELECT * FROM employeesWHERE EXISTS (SELECT 1 FROM departmentsWHERE departments.id = 10);```3.实际应用场景Oracle Exists 语句在以下场景中非常有用:- 检查库存是否充足:在销售商品时,可以使用Exists 语句检查库存中是否存在足够的商品。
- 检查是否存在相似产品:在商品管理中,可以使用Exists 语句检查是否有与新商品相似的商品,从而避免重复上架。
- 检查是否存在相同的记录:在数据清洗和整理过程中,可以使用Exists 语句检查是否存在重复的记录,以便进行进一步的处理。
oracle hint 修改基表
oracle hint 修改基表【最新版】目录1.Oracle Hint 简介2.修改基表的原因3.修改基表的方法4.注意事项和最佳实践5.总结正文1.Oracle Hint 简介Oracle Hint 是 Oracle 数据库中一种用于优化查询性能的技巧。
通过在 SQL 语句中使用 Hint,可以向 Oracle 数据库传递一些特定的信息,让数据库根据这些信息来选择最佳的执行计划。
Hint 可以用于多种场景,如提高查询性能、减少 I/O 操作等。
2.修改基表的原因在数据库管理过程中,有时需要对基表进行修改,以满足业务需求或提高数据处理效率。
例如,当基表的数据规模不断增大,可能需要调整表的物理存储结构,以降低 I/O 开销;或者当业务需求发生变化时,需要对表的列进行添加、修改或删除。
3.修改基表的方法修改基表的方法有很多,下面列举几种常用的方法:(1) 使用 ALTER TABLE 语句ALTER TABLE 是 Oracle 数据库中用于修改表结构的常用语句。
通过ALTER TABLE,可以对表进行添加、修改、删除列等操作。
例如,要给基表添加一个名为 "age" 的列,可以使用以下 SQL 语句:```sqlALTER TABLE base_tableADD age NUMBER;```(2) 使用 CREATE TABLE 语句当需要对基表进行较大的结构修改时,可以考虑使用 CREATE TABLE 语句创建一个新表,然后将原表的数据复制到新表中,并对新表进行结构调整。
例如,要将基表的存储方式改为分区存储,可以使用以下 SQL 语句:```sqlCREATE TABLE new_table(LIKE base_table INCLUDING ALL);INSERT INTO new_tableSELECT * FROM base_table;ALTER TABLE new_tablePARTITION BY RANGE (id);```(3) 使用克隆技术在修改基表时,为了保证数据的安全,可以采用克隆技术创建一个基表的副本,然后在副本上进行修改。
Oraclehint详解
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用法
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⾸先⾮归档状态⼀般是不可能的,稍微重要点的系统都必须开归档。
oraclehint强制索引(转)
oraclehint强制索引(转)oracle1.建议建⽴⼀个以paytime,id,cost的复合索引。
光是在paytime上建⽴索引会产⽣很多随机读。
2.就算建⽴了索引,如果你查询的数据量很⼤的话,也不⼀定会⽤索引,有时候全表扫描速度⽐索引扫描要快!(官⽅⽂档上好像说的是⼤概10%,就是如果你查询的数据占到总数据的10%,全表扫描⽐索引快)。
3.建复合索引语句如下(建议去看看官⽅⽂档,建索引有很多参数,⽽且每个版本的也不⼀定⼀样):CREATE TEST_CSUME_test(PAYTIME,ID, COST)LOGGINGTABLESPACE _ANOPARALLEL;最后说⼀句,好像没有“强制索引”的说法的!追问:我记得有强制索引啊,就是/*+这⾥⾯写的*/,但是我不知道语法追答:你指的是⽤hints去提⽰你查询语句去使⽤哪个索引。
SELECT /*+INDEX(TABLE INDEX_NAME)*/ FROM TABLE可以提⽰ORACLE 去使⽤TABLE 表上已经建好的INDEX_NAME。
ORACLE 官⽅⽂档上说过,这并不是强制的,仅仅是提⽰,优化器可能会选择这个索引,也可能不选择。
不过绝⼤部分情况会按照提⽰的去做!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,不报错例⼦:在⼀些场景下,可能ORACLE不会⾃动⾛索引,这时候,如果对业务清晰,可以尝试使⽤强制索引,测试查询语句的性能。
Oracle HINTS
Oracle HINTSHints:- Hints always force the use of the cost based optimizer (Except RULE).- Use ALIASES for the tablenames in the hints.- Ensure tables are analyzed.- Syntax: /*+ HINT HINT ... */ (In PLSQL the space between the '+' andthe first letter of the hint is vitalso /*+ ALL_ROWS */ is finebut /*+ALL_ROWS */ will cause problems)- Optimizer Mode:FIRST_ROWS, ALL_ROWS Force CBO first rows or all rows.RULE Force Rule if possibleORDERED Access tables in the order of the FROM clauseORDERED_PREDICATES Use in the WHERE clause to apply predicatesin the order that they appear.Does not apply predicate evaluation on index keys- Sub-Queries/views:PUSH_SUBQ Causes all subqueries in a query block to be executed at the earliest possible time.Normally subqueries are executed as the lastis applied is outerjoined or remote or joined with a merge join. (>=7.2)NO_MERGE(v) Use this hint in a VIEW to PREVENT itbeing merged into the parent query. (>=7.2)or use NO_MERGE(v) in parent query blockto prevent view V being mergedMERGE(v) Do merge view V 用于在视图中有group by ,distinct,需要复合合并时打入视图中optimizer_features_enable;_complex_view_mergingMERGE_AJ(v) } Put hint in a NOT IN subquery to perform (>=7.3) HASH_AJ(v) } SMJ anti-join or hash anti-join. (>=7.3)Eg: SELECT .. WHERE deptno is not nullAND deptno NOT IN(SELECT /*+ HASH_AJ */ deptno ...)HASH_SJ(v) } Transform EXISTS subquery into HASH or MERGE MERGE_SJ(v) } semi-join to access "v"PUSH_JOIN_PRED(v) Push join predicates into view VNO_PUSH_JOIN_PRED(v) Do NOT push join predicates- Access:FULL(tab) Use FTS on tabCACHE(tab) If table within < arameter:CACHE_SIZE_THRESHOLD>treat as if it had the CACHE option set.See <arameter:CACHE_SIZE_THRESHOLD>. Only applies if FTS used.NOCACHE(tab) Do not cache table even if it has CACHE option set. Only relevant for FTS.ROWID(tab) Access tab by ROWID directlySELECT /*+ ROWID( table ) */ ...FROM tab WHERE ROWID between '&1' and '&2';CLUSTER(tab) Use cluster scan to access 'tab'HASH(tab) Use hash scan to access 'tab'INDEX(tab [ind]) Use 'ind' to access 'tab'INDEX_ASC(tab [ind]) Use 'ind' to access 'tab' for range scan.INDEX_DESC(tab {ind]) Use descending index range scan(Join problems pre 7.3)INDEX_FFS(tab [ind]) Index fast full scan - rather than FTS.INDEX_COMBINE( tab i1.. i5 )Try to use some boolean combination ofbitmap index/s i1,i2 etcINDEX_SS(tab [ind]) Use 'ind' to access 'tab' with anindex skip scanAND_EQUAL(tab i1.. i5 ) Merge scans of 2 to 5 single column indexes.USE_CONCAT Use concatenation (Union All) for OR (or IN) statements. (>=7.2). See [NOTE:17214.1](7.2 requires <Event:10078>, 7.3 no hint req)NO_EXPAND Do not perform OR-expansion (Ie: Do not use Concatenation).DRIVING_SITE(table) Forces query execution to be done at thesite where "table" resides- Joining:USE_NL(tab) Use table 'tab' as the driving table in aNested Loops join. If the driving row source is a combination of tables name one of thetables in the inner join and the NL shoulddrive off the entire row-source.Does not work unless accompanied by an ORDERED hint.USE_MERGE(tab..) Use 'tab' as the driving table in a sort-merge join.Does not work unless accompanied by an ORDERED hint.USE_HASH(tab1 tab2) Join each specified table with another row source with a hash join. 'tab1' is joined to previous row source using a hash join. (>=7.3)STAR Force a star query plan if possible. A starplan has the largest table in the query last in the join order and joins it with a nested loops join on a concatenated index. The STAR hint applies when there are at least 3 tables and the large table's concatenated index has at least 3 columns and there are no conflicting access or join method hints. (>=7.3)STAR_TRANSFORMATION Use best plan containing a STAR transformation (if there is one)- Parallel Query Option:PARALLEL ( table, <egree> [, <instances>] )Use parallel degree / instances as specifiedPARALLEL_INDEX(table, [ index, [ degree [,instances] ] ] )Parallel range scan for partitioned indexPQ_DISTRIBUTE(tab,out,in) How to distribute rows from tab in a PQ(out/in may be HASH/NONE/BROADCAST/PARTITION)NOPARALLEL(table) No parallel on "table"NOPARALLEL_INDEX(table [,index])- MiscellaneousAPPEND Only valid for INSERT .. SELECT.Allows INSERT to work like direct loador to perform parallel insert. See [NOTE:50592.1] NOAPPEND Do not use INSERT APPEND functionalityREWRITE(v1[,v2]) 8.1+ With a view list use eligible materialized viewWithout view list use any eligible MVNOREWRITE 8.1+ Do not rewrite the queryNO_UNNEST Add to a subquery to prevent it from being unnested UNNEST Unnests specified subquery block if possibleSWAP_JOIN_INPUTS Allows the user to switch the inputs of a join.hints[0]="ALL_ROWS";hints[1]="AND_EQUAL";hints[2]="ANTIJOIN";hints[3]="APPEND";hints[4]="BITMAP";hints[5]="BUFFER";hints[6]="BYPASS_RECURSIVE_CHECK";hints[7]="BYPASS_UJVC";hints[8]="CACHE";hints[9]="CACHE_CB";hints[10]="CACHE_TEMP_TABLE";hints[11]="CARDINALITY";hints[12]="CHOOSE";hints[13]="CIV_GB";hints[14]="COLLECTIONS_GET_REFS";hints[15]="CPU_COSTING";hints[16]="CUBE_GB";hints[17]="CURSOR_SHARING_EXACT";hints[18]="DEREF_NO_REWRITE";hints[19]="DML_UPDATE";hints[20]="DOMAIN_INDEX_NO_SORT";hints[21]="DOMAIN_INDEX_SORT";hints[22]="DRIVING_SITE";hints[23]="DYNAMIC_SAMPLING";hints[24]="DYNAMIC_SAMPLING_EST_CDN";hints[25]="EXPAND_GSET_TO_UNION";hints[26]="FACT";hints[27]="FIRST_ROWS";hints[28]="FORCE_SAMPLE_BLOCK";hints[29]="FULL";hints[30]="GBY_CONC_ROLLUP";hints[31]="GLOBAL_TABLE_HINTS";hints[32]="HASH";hints[33]="HASH_AJ";hints[34]="HASH_SJ";hints[35]="HWM_BROKERED";hints[36]="IGNORE_ON_CLAUSE";hints[37]="IGNORE_WHERE_CLAUSE"; hints[38]="INDEX_ASC";hints[39]="INDEX_COMBINE";hints[40]="INDEX_DESC";hints[41]="INDEX_FFS";hints[42]="INDEX_JOIN";hints[43]="INDEX_RRS";hints[44]="INDEX_SS";hints[45]="INDEX_SS_ASC";hints[46]="INDEX_SS_DESC";hints[47]="INLINE";hints[48]="LEADING";hints[49]="LIKE_EXPAND";hints[50]="LOCAL_INDEXES";hints[51]="MATERIALIZE";hints[52]="MERGE";hints[53]="MERGE_AJ";hints[54]="MERGE_SJ";hints[55]="MV_MERGE";hints[56]="NESTED_TABLE_GET_REFS"; hints[57]="NESTED_TABLE_SET_REFS"; hints[58]="NESTED_TABLE_SET_SETID"; hints[59]="NL_AJ";hints[60]="NL_SJ";hints[61]="NO_ACCESS";hints[62]="NO_BUFFER";hints[63]="NO_EXPAND";hints[64]="NO_EXPAND_GSET_TO_UNION"; hints[65]="NO_FACT";hints[66]="NO_FILTERING";hints[67]="NO_INDEX";hints[68]="NO_MERGE";hints[69]="NO_MONITORING";hints[70]="NO_ORDER_ROLLUPS";hints[71]="NO_PRUNE_GSETS";hints[72]="NO_PUSH_PRED";hints[73]="NO_PUSH_SUBQ";hints[74]="NO_QKN_BUFF";hints[75]="NO_SEMIJOIN";hints[76]="NO_STATS_GSETS";hints[77]="NO_UNNEST";hints[78]="NOAPPEND";hints[79]="NOCACHE";hints[80]="NOCPU_COSTING";hints[81]="NOPARALLEL";hints[82]="NOPARALLEL_INDEX"; hints[83]="NOREWRITE";hints[84]="OR_EXPAND";hints[85]="ORDERED";hints[86]="ORDERED_PREDICATES"; hints[87]="OVERFLOW_NOMOVE"; hints[88]="PARALLEL";hints[89]="PARALLEL_INDEX";hints[90]="PIV_GB";hints[91]="PIV_SSF";hints[92]="PQ_DISTRIBUTE";hints[93]="PQ_MAP";hints[94]="PQ_NOMAP";hints[95]="PUSH_PRED";hints[96]="PUSH_SUBQ";hints[97]="REMOTE_MAPPED";hints[98]="RESTORE_AS_INTERVALS"; hints[99]="REWRITE";hints[100]="RULE";hints[101]="SAVE_AS_INTERVALS"; hints[102]="SCN_ASCENDING";hints[103]="SELECTIVITY";hints[104]="SEMIJOIN";hints[105]="SEMIJOIN_DRIVER";hints[106]="SKIP_EXT_OPTIMIZER"; hints[107]="SQLLDR";hints[108]="STAR";hints[109]="STAR_TRANSFORMATION"; hints[110]="SWAP_JOIN_INPUTS"; hints[111]="SYS_DL_CURSOR";hints[112]="SYS_PARALLEL_TXN"; hints[113]="SYS_RID_ORDER";hints[114]="TIV_GB";hints[115]="TIV_SSF";hints[116]="UNNEST";hints[117]="USE_ANTI";hints[118]="USE_CONCAT";hints[119]="USE_HASH";hints[120]="USE_MERGE";hints[121]="USE_NL";hints[122]="USE_SEMI";hints[123]="USE_TTT_FOR_GSETS";hints[124]="BYPASS_RECURSIVE_CHECK"; hints[125]="BYPASS_UJVC";hints[126]="CACHE_CB";hints[127]="CACHE_TEMP_TABLE";hints[128]="CIV_GB";hints[129]="COLLECTIONS_GET_REFS";hints[130]="CUBE_GB";hints[131]="CURSOR_SHARING_EXACT"; hints[132]="DEREF_NO_REWRITE";hints[133]="DML_UPDATE";hints[134]="DOMAIN_INDEX_NO_SORT"; hints[135]="DOMAIN_INDEX_SORT";hints[136]="DYNAMIC_SAMPLING";hints[137]="DYNAMIC_SAMPLING_EST_CDN"; hints[138]="EXPAND_GSET_TO_UNION"; hints[139]="FORCE_SAMPLE_BLOCK";hints[140]="GBY_CONC_ROLLUP";hints[141]="GLOBAL_TABLE_HINTS";hints[142]="HWM_BROKERED";hints[143]="IGNORE_ON_CLAUSE";hints[144]="IGNORE_WHERE_CLAUSE"; hints[145]="INDEX_RRS";hints[146]="INDEX_SS";hints[147]="INDEX_SS_ASC";hints[148]="INDEX_SS_DESC";hints[149]="LIKE_EXPAND";hints[150]="LOCAL_INDEXES";hints[151]="MV_MERGE";hints[152]="NESTED_TABLE_GET_REFS"; hints[153]="NESTED_TABLE_SET_REFS"; hints[154]="NESTED_TABLE_SET_SETID"; hints[155]="NO_EXPAND_GSET_TO_UNION"; hints[156]="NO_FACT";hints[157]="NO_FILTERING";hints[158]="NO_ORDER_ROLLUPS";hints[159]="NO_PRUNE_GSETS";hints[160]="NO_STATS_GSETS";hints[161]="NO_UNNEST";hints[162]="NOCPU_COSTING";hints[163]="OVERFLOW_NOMOVE";hints[164]="PIV_GB";hints[165]="PIV_SSF";hints[166]="PQ_MAP";hints[167]="PQ_NOMAP";hints[168]="REMOTE_MAPPED";hints[169]="RESTORE_AS_INTERVALS";hints[170]="SAVE_AS_INTERVALS";hints[171]="SCN_ASCENDING";hints[172]="SKIP_EXT_OPTIMIZER";hints[173]="SQLLDR";hints[174]="SYS_DL_CURSOR";hints[175]="SYS_PARALLEL_TXN";hints[176]="SYS_RID_ORDER";hints[177]="TIV_GB";hints[178]="TIV_SSF";hints[179]="UNNEST";hints[180]="USE_TTT_FOR_GSETS";Oracle SQL hints/*+ hint *//*+ hint(argument) *//*+ hint(argument-1 argument-2) */All hints except /*+ rule */ cause the CBO to be used. Therefore, it is good practise to analyze the underlying tables if hints are used (or the query is fully hinted. There should be no schema names in hints. Hints must use aliases if alias names are used for table names. So the following is wrong:select /*+ index(scott.emp ix_emp) */ from scott.emp emp_aliasbetter:select /*+ index(emp_alias ix_emp) */ ... from scott.emp emp_aliasWhy using hintsIt is a perfect valid question to ask why hints should be used. Oracle comes with an optimizer that promises to optimize a query's execution plan. When this optimizer is really doing a good job, no hints should be required at all. Sometimes, however, the characteristics of the data in the database are changing rapidly, so that the optimizer (or more accuratly, its statistics) are out of date. In this case, a hint could help. It must also be noted, that Oracle allows to lock the statistics when they look ideal which should make the hints meaningless again.Hint categoriesHints can be categorized as follows:Hints for Optimization Approaches and Goals,Hints for Access Paths, Hints for Query Transformations,Hints for Join Orders,Hints for Join Operations,Hints for Parallel Execution,Additional Hints Documented HintsHints for Optimization Approaches and GoalsALL_ROWSOne of the hints that 'invokes' the Cost based optimizerALL_ROWS is usually used for batch processing or data warehousing systems.FIRST_ROWSOne of the hints that 'invokes' the Cost based optimizerFIRST_ROWS is usually used for OLTP systems.CHOOSEOne of the hints that 'invokes' the Cost based optimizerThis hint lets the server choose (between ALL_ROWS and FIRST_ROWS, based on statistics gathered.RULEThe RULE hint should be considered deprecated as it is dropped from Oracle9i2.See also the following initialization parameters: optimizer_mode, optimizer_max_permutations, optimizer_index_cost_adj, optimizer_index_caching and Hints for Access PathsCLUSTERPerforms a nested loop by the cluster index of one of the tables.FULLPerforms full table scan.HASHHashes one table (full scan) and creates a hash index for that table. Then hashes other table and uses hash index to find corresponding records. Therefore not suitable for < or > join conditions.ROWIDRetrieves the row by rowidINDEXSpecifying that index index_name should be used on table tab_name: /*+ index (tab_name index_name) */Specifying that the index should be used the the CBO thinks is most suitable. (Not always a good choice).Starting with Oracle 10g, the index hint can be described: /*+ index(my_tab my_tab(col_1, col_2)) */. Using the index on my_tab that starts with the columns col_1 and col_2. INDEX_ASCINDEX_COMBINEINDEX_DESCINDEX_FFSINDEX_JOINNO_INDEXAND_EQUALThe AND_EQUAL hint explicitly chooses an execution plan that uses an access path that merges the scans on several single-column indexes Hints for Query Transformations FACTThe FACT hint is used in the context of the star transformation to indicate to the transformation that the hinted table should be considered as a fact table.MERGENO_EXPANDNO_EXPAND_GSET_TO_UNIONNO_FACTNO_MERGENOREWRITEREWRITESTAR_TRANSFORMATIONUSE_CONCAT Hints for Join OperationsDRIVING_SITEHASH_AJHASH_SJLEADINGMERGE_AJMERGE_SJNL_AJNL_SJUSE_HASHUSE_MERGEUSE_NL Hints for Parallel ExecutionNOPARALLELPARALLELNOPARALLEL_INDEXPARALLEL_INDEXPQ_DISTRIBUTE Additional HintsANTIJOINAPPENDIf a table or an index is specified with nologging, this hint applied with an insert statement produces a direct path insert which reduces generation of redo.BITMAPBUFFERCACHECARDINALITYCPU_COSTINGDYNAMIC_SAMPLINGINLINEMATERIALIZENO_ACCESSNO_BUFFERNO_MONITORINGNO_PUSH_PREDNO_PUSH_SUBQNO_QKN_BUFFNO_SEMIJOINNOAPPENDNOCACHEOR_EXPANDORDEREDORDERED_PREDICATESPUSH_PREDPUSH_SUBQQB_NAMERESULT_CACHE (Oracle 11g)SELECTIVITYSEMIJOINSEMIJOIN_DRIVERSTARThe STAR hint forces a star query plan to be used, if possible. A star plan has the largest table in the query last in the join order and joins it with a nested loops join on a concatenated index. The STAR hint applies when there are at least three tables, the large table's concatenated index has at least three columns, and there are no conflicting access or join method hints. The optimizer also considers different permutations of the small tables.SWAP_JOIN_INPUTSUSE_ANTIUSE_SEMI Undocumented hints:BYPASS_RECURSIVE_CHECKWorkaraound for bug 1816154BYPASS_UJVCCACHE_CBCACHE_TEMP_TABLECIV_GBCOLLECTIONS_GET_REFSCUBE_GBCURSOR_SHARING_EXACTDEREF_NO_REWRITEDML_UPDATEDOMAIN_INDEX_NO_SORTDOMAIN_INDEX_SORTDYNAMIC_SAMPLINGDYNAMIC_SAMPLING_EST_CDNEXPAND_GSET_TO_UNIONFORCE_SAMPLE_BLOCKGBY_CONC_ROLLUPGLOBAL_TABLE_HINTSHWM_BROKEREDIGNORE_ON_CLAUSEIGNORE_WHERE_CLAUSEINDEX_RRSINDEX_SSINDEX_SS_ASCINDEX_SS_DESCLIKE_EXPANDLOCAL_INDEXESMV_MERGENESTED_TABLE_GET_REFS NESTED_TABLE_SET_REFS NESTED_TABLE_SET_SETID NO_FILTERINGNO_ORDER_ROLLUPSNO_PRUNE_GSETSNO_STATS_GSETSNO_UNNESTNOCPU_COSTING OVERFLOW_NOMOVEPIV_GBPIV_SSFPQ_MAPPQ_NOMAPREMOTE_MAPPED RESTORE_AS_INTERVALS SAVE_AS_INTERVALSSCN_ASCENDINGSKIP_EXT_OPTIMIZER SQLLDRSYS_DL_CURSORSYS_PARALLEL_TXNSYS_RID_ORDERTIV_GBTIV_SSFUNNESTUSE_TTT_FOR_GSETS。
oracle强制索引写法
oracle强制索引写法如果你需要优化你的Oracle数据库查询,强制索引就是一个很好的选择。
因为Oracle的优化器趋向于使用统计数据来决定查询最优执行计划,这可能导致有些查询性能不佳。
此时强制索引可以让你显式地指定使用哪个索引,从而达到更好的性能。
以下是一些关于如何写Oracle强制索引的技巧:1. 使用HINTS在查询语句中使用HINTS可以指定强制使用某个索引。
例如:```SELECT /*+ index(emp emp_idx) */ emp_no, emp_name FROM emp WHERE dept_no = '10';```在这个例子中,我们明确指定了使用索引`emp_idx`来查询表`emp`中的数据。
2. 创建视图你也可以创建一个视图,并在视图中使用你想要的索引。
这样做的好处是,你可以轻松地修改查询语句而不必更改强制索引。
例如,如果你希望使用索引`emp_idx`来查询表`emp`中的数据,你可以创建一个名为`emp_view`的视图:```CREATE VIEW emp_view AS SELECT /*+ index(emp emp_idx) */emp_no, emp_name FROM emp;```现在,当你查询`emp_view`时,就会自动使用`emp_idx`索引。
例如:```SELECT * FROM emp_view WHERE dept_no = '10';```3. 为查询语句重命名表你可以为查询语句中的表重命名,并在重命名后的表上使用强制索引。
这种方法可以让你不必创建视图来使用强制索引。
例如,在查询`emp`表时,你可以为它取一个别名`e`,并强制使用索引`emp_idx`:```SELECT /*+ index(e emp_idx) */ emp_no, emp_name FROM emp e WHERE dept_no = '10';```通过这种方法,你可以把你想要使用的索引直接写在查询语句中,而不必修改表结构或创建视图。
hint简介
ORACLE的HINT详解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 WHERE EMP_NO='SCOTT';2. /*+FIRST_ROWS*/表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.例如:SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM3. /*+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进行访问.例如:ROWID>='AAAAAAAAAAAAAA'AND EMP_NO='SCOTT';7. /*+CLUSTER(TABLE)*/提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.例如:SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMSWHERE DPT_NO='TEC304' ANDBSEMPMS.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*/索引,将选择出位图索引的布尔组合方式.例如:SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMIHIREDATE_BMI)*/ * FROM BSEMPMSWHERE SAL<5000000 AND HIREDATE11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/提示明确命令优化器使用索引作为访问路径.例如:SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE12. /*+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(BSEMPMSIN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHEREEMP_NO='SCOTT' AND DPT_NO='TDC306';15. /*+USE_CONCAT*/对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询. 例如:SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHEREDPT_NO='TDC506' AND SEX='M';16. /*+NO_EXPAND*/对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.例如:SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHEREDPT_NO='TDC506' AND SEX='M';17. /*+NOWRITE*/禁止对查询块的查询重写操作.18. /*+REWRITE*/可以将视图作为参数.能够对视图的各个查询进行相应的合并.例如: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 TABLE1A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 ANDB.COL1=C.COL1;22. /*+USE_NL(TABLE)*/将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.例如:SELECT /*+ORDERED USE_NL(BSEMPMS)*/BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;23. /*+USE_MERGE(TABLE)*/将指定的表与其他行源通过合并排序连接方式连接起来.例如:SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;24. /*+USE_HASH(TABLE)*/将指定的表与其他行源通过哈希连接方式连接起来.例如:SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHEREBSEMPMS.DPT_NO=BSDPTMS.DPT_NO;25. /*+DRIVING_SITE(TABLE)*/强制与ORACLE所选择的位置不同的表进行查询执行.例如:SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHEREBSEMPMS.DPT_NO=DEPT.DPT_NO;将指定的表作为连接次序中的首表.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: 指定不使用哪些索引select /*+ no_index(emp ind_emp_sal ind_emp_deptno)*/ * from emp where deptno=200 and sal>300;32. parallelselect /*+ parallel(emp,4)*/ * from emp where deptno=200 and sal>300;另:每个SELECT/INSERT/UPDATE/DELETE命令后只能有一个/*+ */,但提示内容可以有多个,可以用逗号分开,空格也可以。
