Oracle Hints是一种机制,用来告诉优化器按照我们的制定的方式生成执行计划,而不是根据它自己的分析生成执行计划。
一、我们可以用Oracle Hints来实现
1) 使用的优化器的类型。
2) 基于代价的优化器的优化目标,是all_rows还是first_rows。
3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用rowid。
4) 表之间的连接类型。
5) 表之间的连接顺序。
6) 语句的并行程度。
二、Hints应用要求
Hints只应用在它们所在sql语句块(statement block,由select、update、delete、insert关键字标识)上,对其它SQL语句或语句的其它部分没有影响。
三、使用Oracle Hints的语法
{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */
or
{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...
1) 如果包含多个提示,则每个提示之间需要用一个或多个空格隔开。
2) text 是其它说明hints的注释性文本。
3)使用表别名。如果在查询中指定了表别名,那么提示必须也使用表别名。例如:
select /*+ index(d,demo_idx) */ * from demo d;
4)不要在提示中使用模式名称:如果在提示中指定了模式的所有者,那么提示将被忽略。例如:
select /*+ index(scott.emp,demo_idx) */ * from demo d;
四、Hints的具体用法
优化器相关的hints
1、/*+ ALL_ROWS */
表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化。
SELECT /*+ ALL+_ROWS*/ DEMO_NO,DEMO_NAME,DEMO_ADDR FROM DEMO WHERE DEMO_NO='ITWUYI';
2、/*+ FIRST_ROWS(n) */
表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化。
SELECT /*+FIRST_ROWS(20) */ DEMO_NO,DEMO_NAME,DEMO_ADDR FROM DEMO WHERE DEMO_NO='ITWUYI';
3、/*+ RULE*/
表明对语句块选择基于规则的优化方法。
SELECT /*+ RULE */ DEMO_NO,DEMO_NAME,DEMO_ADDR FROM DEMO WHERE DEMO_NO='ITWUYI';
访问路径相关的hints
1、/*+ FULL(TABLE)*/
表明对表选择全局扫描的方法。
SELECT /*+FULL(A)*/ DEMO_NO,DEMO_NAME FROM DEMO A WHERE DEMO_NO='ITWUYI';
2、/*+ INDEX(TABLE INDEX_NAME) */
表明对表选择索引的扫描方法。
SELECT /*+INDEX(DEMO SEX_INDEX) */ * FROM DEMO WHERE SEX='M';
3、/*+ INDEX_ASC(TABLE INDEX_NAME)*/
表明对表选择索引升序的扫描方法。
SELECT /*+INDEX_ASC(DEMO PK_DEMO) */ * FROM DEMO WHERE DPT_NO='ITWUYI';
4、/*+ INDEX_COMBINE*/
为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式。
SELECT /*+INDEX_COMBINE(DEMO SAL_BMI HIREDATE_BMI) */ * FROM DEMO WHERE SAL<5000000 AND HIREDATE;
5、/*+ INDEX_JOIN(TABLE INDEX_NAME1 INDEX_NAME2) */
当谓词中引用的列都有索引的时候,可以通过指定采用索引关联的方式,来访问数据。
select /*+ index_join(t t_ind t_bm) */ id from t where id=100 and object_name='ITWUYI';
6、/*+ INDEX_DESC(TABLE INDEX_NAME)*/
表明对表选择索引降序的扫描方法。
SELECT /*+INDEX_DESC(DEMO PK_DEMO) */ * FROM DEMO WHERE DPT_NO='ITWUYI';
7、/*+ INDEX_FFS(TABLE INDEX_NAME) */
对指定的表执行快速全索引扫描,而不是全表扫描的办法。
SELECT /* + INDEX_FFS(DEMO IN_EMPNAM)*/ * FROM DEMO WHERE DPT_NO='TEC305';
8、/*+ INDEX_SS(T T_IND) */
从9i开始,oracle引入了这种索引访问方式。当在一个联合索引中,某些谓词条件并不在联合索引的第一列时,可以通过Index Skip Scan来访问索引获得数据。当联合索引第一列的唯一值个数很少时,使用这种方式比全表扫描效率高。