您的位置:首页 > 数据库 > Oracle

Oracle Hints

2016-12-30 16:52 225 查看
hits 说明:

–======Hints for Optimization Approaches and Goals

/+ALL_ROWS/ –对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.

SELECT /+ ALL_ROWS /

employee_id, last_name, salary, job_id

FROM employees

WHERE employee_id = 7566;

/+FIRST_ROWS(n)/ –对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化. n 为任意正数

–不能用于DELETE 、UPDATE 、含有排序和聚合的select 语句

SELECT /+ FIRST_ROWS(10) /

employee_id, last_name, salary, job_id

FROM employees

WHERE department_id = 20;

/+CHOOSE/ –如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;

SELECT /+ CHOOSE /

employee_id, last_name, salary, job_id

FROM employees

WHERE employee_id = 7566;

/+RULE/ –对语句块选择基于规则的优化方法.

–======Hints for Access Paths

/+ FULL(TABLE)/ –对表选择全局扫描的方法.

/+ ROWID(TABLE)/ –明确表明对指定表根据ROWID进行访问.

/+ CLUSTER(TABLE)/ –明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.

/+ INDEX(TABLE INDEX_NAME)/ –对表选择索引的扫描方法.

/+ INDEX_ASC(TABLE INDEX_NAME)/ –对表选择索引升序的扫描方法.

/+ INDEX_DESC(TABLE INDEX_NAME)/ –对表选择索引降序的扫描方法.

/+ INDEX_COMBINE/ –指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式

SELECT /+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)/ * FROM BSEMPMS WHERE SAL<5000000 AND HIREDATE

/+ INDEX_JOIN(TABLE INDEX_NAME)/ –明确命令优化器使用索引作为访问路径.

/+ INDEX_FFS(TABLE INDEX_NAME)/ –对指定的表执行快速全索引扫描,而不是全表扫描的办法.

–======Hints for Query Transformations

/+ USE_CONCAT/ –对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.

SELECT /+USE_CONCAT/ *

FROM employees

WHERE employee_id > 50

OR salary < 50000;

/+ NO_EXPAND/ –与 USE_CONCAT 相反,阻止Oracle将OR操作按UNION ALL操作执行

SELECT /+ NO_EXPAND / *

FROM employees e, departments d

WHERE e.manager_id = 108

OR d.department_id = 110;

/+ MERGE(TABLE)/ –能够对视图的各个查询进行相应的合并.merge 的含义是把veiw展开,把sql从(view join view/table) 变成多个table 相互jion的写法, 执行计划中也不会出现view的acces path

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

/+ NO_MERGE(TABLE)/ –阻止将复杂的视图与调用该视图的语句合并,不改写view,不把view展开~ 执行计划中必定出现view的access path

/+ UNNEST / –对子查询展开,别让子查询孤单地嵌套(nest)在里面

–如果一个查询中的where 中出现 view 或者 子查询。那么Oracle的CBO在解析着这个SQL之前要做转换,把VIEW或者子查询”打开”(叫做unnest), 然后可以把主查询和子查询中的表通过表连接的方式,生成执行计划

–场景:首先,子查询的返回结果集应该较小,然后外围查询的输入的distinct value也应该较小

/+ NO_UNNEST / –让子查询不展开,让它嵌套(nest)在里面;不要“打开” VIEW或者子查询~ 这样VIEW或者子查询只能被当作一个独立查询,来进行解析,里面的表无法和主查询中的表进行连接

select hao1.object_id

from hao1

where exists (select /+no_unnest/

1

from hao2

where hao1.object_id = hao2.object_id * 10);

/+ PUSH_PRED / –unmergeable view来说,merge hint无效;hint push_pred作为补充;push_pred则是针对unmergeable view使用外部查询谓词

select /+push_pred(haoview)/ –使用这里的hint push_pred强制优化器将谓词merge进view中,可见到“VIEW PUSHED PREDICATE”

hao3.object_name

from hao3, haoview

where hao3.object_name = haoview.object_name(+) –haoview放到outer join的右侧,这是haoview就属于unmergeable view了,优化器默认无法将谓词merge进这个haoview中,于是就看到了haoview单独先执行

and hao3.object_id = 999;

/+ NO_PUSH_PRED / –no_push_pred的含义是view只作为一个view先得出结果,然后根据连接条件和其他的table/view根据连接条件,进行连接

/+ PUSH_SUBQ / –是为了让子查询最先进行join

–The push_subq hint is used to force all subqueries in the query block to be executed at the earliest possible place in the execution plan

–With push_subq, the subqueries are often executed before the outer query is executed.

–the push_subq hint has no effect if the subquery is using a sort merge join, or when the subquery references a remote table

select /+push_subq(@tmp)/

hao1.object_name

from hao1, hao2, hao4

where hao1.object_name like ‘%a%’

and hao1.object_id + hao2.object_id > 50

and hao4.object_type = hao1.object_type

and 11 in (SELECT /+QB_Name(tmp)/

hao3.object_id

FROM hao3

WHERE hao1.object_id = hao3.object_id)

/+ NO_PUSH_SUBQ /

/+ REWRITE / –查询重写,按物化视图对语句进行重写

/+ NO_REWRITE / –关闭REWRITE功能

/+ STAR_TRANSFORMATION / –强制Oracle对星型模型的访问转换为子查询,并按相关Bitmap索引进行访问

/+ FACT / –与STAR_TRANSFORMATION Hint配合,指定哪个表为事实表

/+ NO_FACT / –与STAR_TRANSFORMATION Hint配合,指定哪个表不为事实表

–======Hints for Join Orders

/+ORDERED/ –根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.

/+ LEADING(TABLE)/ –将指定的表作为连接次序中的首表.如果指定ORDERED提示,它覆盖所有LEADING提示。

–======Hints for Join Operations

/+ USE_NL(TABLE)/ –将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表:

–use_nl如果只带了一个表名作为参数,则该表为被驱动表(inner table);

–如果带了2个以上的参数,Oracle并没有指出use_nl(a,b)中哪个是驱动表,所以常使用ordered或者LEADING或者full()或者index()来强化我们的目标

select /+ ordered use_nl(employees) / –departments作为驱动表

first_name, departments.department_id

from departments, employees

where employees.department_id = departments.department_id;

/+ NO_USE_NL(TABLE)/

/+ USE_NL_WITH_INDEX(TABLE)/

/+ USE_MERGE(TABLE)/ –将指定的表与其他行源通过合并排序连接方式连接起来.

/+ NO_USE_MERGE(TABLE)/ –

/+ USE_HASH(TABLE)/ –将指定的表与其他行源通过哈希连接方式连接起来

/+ NO_USE_HASH(TABLE)/

–======Hints for Parallel Execution

/+ ENABLE_PARALLEL_DML/

/+ PARALLEL(tanme n)/

/+ NO_PARALLEL(tanme n)/

/+ PARALLEL_INDEX /

/+ NO_PARALLEL_INDEX /

/+ PQ_DISTRIBUTE /

–======Additional Hints

/+ CACHE(TABLE)/ –当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端

/+ NOCACHE(TABLE)/ –当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端

/+ opt_param(‘_b_tree_bitmap_plans’,’false’) / –让优化器不能使用BITMAP CONVERSION TO ROWIDS

/+ QB_NAME(subq) nl_sj/ –定义查询快别名,用于复杂查询的子查询定义

/+ CURSOR_SHARING_EXACT /

/+ PUSH_PRED /

/+ NO_PUSH_PRED /

/+ PUSH_SUBQ /

/+ NO_PUSH_SUBQ /

/+ CURSOR_SHARING_EXACT /
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: