与优化器模式相关的Hint
- ALl_ROWS 让优化器启用CBO
/*+ all_rows */
- first_rows(n) 让优化器启用CBO 模式,而且得到目标sql的执行计划是会选择那些能以最快时间返回n条记录的执行路径
/*+ first_rows */
- rule 启用RBO
/*+ rule */
与表访问相关
/*+ full */
对目标表执行全表扫描 。/*+ rowid(tablename) */
针对单个表的HInt,他的含义是让优化器执行rowid 扫描,只有目标sql中使用了含rowid的where 条件时,rowid hint 才有意义。
与索引访问相关的hint
- index 对目标表上的目标执行索引扫描操作
/* index (表名 目标索引(可多个)) */
/* index (表名) */
/* index (表名 目标索引对应的列名(可多个)) */
- no_index 与index 相反
/* no_index (表名 目标索引(可多个)) */
/* no_index (表名) */
- index_desc 执行索引时,降序扫描
/* index_desc (表名 目标索引(可多个)) */
/* index_desc (表名) */
- index_combine 对目标表上的多个目标索引执行位图布尔运算
/* index_combine (表名 目标索引(可多个)) */
/* index_combine (表名) */
5 index_join 针对单个目标表。对目标表上的多个目标索引执行 index join 操作。 主要作用是把两个独立的单列索引联合起来一启用。
The INDEX_JOIN
hint explicitly instructs the optimizer to use an index join as an access path. For the hint to have a positive effect, a sufficiently small number of indexes must exist that contain all the columns required to resolve the query./*+ index_join(表名 目标索引(可多个)) */
/*+ index_join(表名) */
前提条件: select的所有查询列都存在目标表的多个目标索引中
- and_equal 对目标表的多个目标索引执行 index_merge操作。最少指定两个索引,最多指定5个。但是从Oracle 10g开始,and_equal操作被废弃(depricated)掉,Oracle不再支持。
/*+ and_equal(表名 目标索引(可多个)) */
/*+ and_equal(表名) */
- index_ffs 针对单个目标表。 对目标表的目标索引执行索引快速全扫描操作。
/* index_ffs (表名 目标索引(可多个)) */
/* index_ffs (表名) */
与表连接顺序相关的hint
- ordered 针对多个目标表,让优化器对多个目标表执行表连接操作时,按照sql的from字句中出现的顺序从左到右依次进行连接
/*+ ordered */
- leading 针对多个目标表,让优化器将指定的多个表的连接结果作为目标sql表连接过程中的驱动结果集,并且将leading hint 中从左到右出现的第一个目标表作为整个表连接的首个驱动表
/*+ leading(表1 表2 表n) */
与表连接方法相关的Hint
- use_merge 针对多个目标表,让优化器将我们指定的多个表作为被驱动表与其他表或结果集做排序合并连接
/*+ use_merge(表1 表2 表n) */
/*+ use_merge(表1,表2,...,表n) */
- no_use_merge 针对多个目标表,不让优化器将我们指定的多个表作为被驱动表与其他表或结果集做排序合并连接
/*+ no_use_merge(表1 表2 表n) */
/*+ no_use_merge(表1,表2,...,表n) */
- use_nl 针对多个目标表,让优化器将我们指定的多个表作为被驱动表与其他表或结果集做嵌套循环连接
/*+ use_nl(表1 表2 表n) */
/*+ use_nl(表1,表2,...,表n) */
- no_use_nl 针对多个目标表,不让优化器将我们指定的多个表作为被驱动表与其他表或结果集做嵌套循环连接
/*+ no_use_nl(表1 表2 表n) */
/*+ no_use_nl(表1,表2,...,表n) */
- use_hash 针对多个目标表,让优化器将我们指定的多个表作为被驱动表与其他表或结果集做哈希连接
/*+ use_hash(表1 表2 表n) */
/*+ use_hash(表1,表2,...,表n) */
- no_use_hash 针对多个目标表,不让优化器将我们指定的多个表作为被驱动表与其他表或结果集做哈希连接
/*+ no_use_hash(表1 表2 表n) */
/*+ no_use_hash(表1,表2,...,表n) */
7 merge_aj 针对子查询,让优化器对相关目标表执行排序合并反连接/*+ merge_aj */
8 nl_aj 针对子查询,让优化器对相关目标表执行嵌套循环反连接/*+ nl_aj */
9 hash_aj 针对子查询,让优化器对相关目标表执行哈希反连接/*+ hash_aj */
- merge_sj 针对子查询,让优化器对相关目标表执行排序合并半连接
/*+ merge_sj */
- nl_sj 针对子查询,让优化器对相关目标表执行嵌套循环半连接
/*+ nl_sj */
- hash_sj 针对子查询,让优化器对相关目标表执行哈希半连接
/*+ hash_sj */
产生的条件:
当有not in(select list) 或者 not exists(select list) 的时候就容易发生NL_SJ或者HASH_SJ, 是因为ORACLE默认会将子查询展开,让子查询外面的条件融入到子查询里面, 这时就要注意了,80%的情况是好的, 但有的情况下可能展开以后带来灾难性的变化, 会让执行计划变的很糟糕。
功能:可以改变NL_SJ的执行计划, 也就是当执行计划中出现:NEST LOOP SEMI 的时候, 可以用之来改变执行计划。
与查询转换相关的hint
- use_concat 针对整个SQL的hint ,让优化器对目标sql使用IN_LIST 扩展(IN_List exception )或OR扩展(OR Exception )
/*+ use_concat */
- no_expand 针对整个SQL的hint ,use_concat 的反义hint
/*+ no_expand */
- merge 针对单个目标视图的hint,让优化器对目标视图执行视图合并(view merging)
/*+ merge(目标视图) */
如果是内嵌视图,此时的hint不要出现视图名
- no_merge 针对单个目标视图的hint,是 merge的反义hint
/*+ no_merge(目标视图) */
如果是内嵌视图,此时的hint不要出现视图名
- Push_pred /no_push_pred: If you have a non-mergeable view (possible because of a no_merge hint) in your query, how should you operate the join from other tables; should you create one large view result and join it once (no_push_pred) or should you push the join predicate down into the view definition and recreate the view result set for every driving row from another table (push_pred)。
同样查询中必须至少有view的存在,并且这个view是不可以被merge的情况下才可以使用 push_pred/no_push_pred。
no_push_pred的含义是view只作为一个view先得出结果,然后根据连接条件和其他的table/view根据连接条件,进行连接。
Push_pred的含义是我将“连接条件”插入到view中, 使用其他结果集根据连接条件去驱动这个view进行连接(也就是被push_pred的view只能作为nested-loop的外。
- unnest 针对子查询的hint,让优化器对目标sql中的子查询执行子查询展开
/*+ unnest */
- no_unnest 针对子查询的hint,unnest的反义hint
/*+ no_unnest */
- expand_table 针对单个目标表的hint,让优化器在不考虑成本的情况下对目标表执行表扩展。
/*+ expand_table(目标表) */
- no_expand_table 针对单个目标表的hint,expand_table的反义hint
/*+ no_expand_table(目标表) */