ORACLE里的hint(一)
Hint是Oracle数据库里SQL优化的终极手段,通常用于指定目标SQL的执行计划。正是因为Hint可以直接影响优化器对执行计划的选择,所以在其它常规调整手段(如重新收集统计信息等,以后的文章会对这方面写个专题)失效的情况下,它依然可以对目标SQL的执行计划做出调整。
Hint实际上是一种特殊的注释,它以一种固定的格式和位置出现在SQL语句的SQL文本中,它可以影响优化器对于执行计划的选择,但是这种影响不是强制性的,优化器在某些情况下可能会忽略目标SQL的hint,即使这个hint在语法和语义上都是有效的。
如果目标SQL中SQL文本中出现了hint,则优化器在面临各种可能的,不同执行路径的选择时,其判断标准将不再仅仅是其原先的判断标准,而是会将hint也一并考虑进来。如果优化器判断这个hint给出的建议是合适的,可以应用,就会直接遵循这个hint给出的建议,并据此来选择执行计划;反之,优化器就会忽略该hint,仍然采用原先的判断标准来选择执行计划。
Hint的具体用法如下:
Hint必须以以下格式出现在SQL文本中:
/*+ (具体的Hint内容)*/
例如:select /*+ gather_plan_statistics*/ t1.empno,t1.ename,t2.dname from scott.emp t1,scott.dept t2 where t1.deptno=t2.deptno;
固定位置是指Hint在SQL文本中必须紧随关键字SELECT,INSERT,UPDATE,DELETE或MERGE之后,这也意味着SELECT语句,INSERT语句,UPDATE语句,DELETE语句和MERGE语句中都可以使用Hint。
对于Hint格式,有以下几点需要注意:
一是Hint第一个(*)号和(+)之间不能有空格
二是Hint(+)和具体内容之间可以有空格,也可以没有空格,但通常有空格
三是Hint具体内容可以是单个Hint也可以是多个Hint组合,但是后者,各个Hint间至少需要一个空格来彼此分隔。
另外对于Hint的用法也有几点需要注意:
1.Hint指定具体对象时(比如指定表名或者索引名),不能带上该对象所在SCHEMA的名称,即使该SQL文本中已经有对应的SCHEMA名称。
2.在Hint中指定具体表名时,如果该表在对应SQL文本中有别名,则应该使用该表的别名。
3.Oracle数据库中Hint生效的范围仅限于它本身所在的Query Block,如果想将Hint生效的范围扩展到它所在的Query Block之外,而又没有在该Hint指定其生效的Query Block名称的话,则Oracle会忽略该Hint。