构筑高速运行的SQL语句(五)

摘自《成功之路:Oracle 11g学习笔记》

 17.3.5 

提示(Hint

提示(Hint)是嵌入到SQL语句中的一些指令,用于改变SQL语句的执行计划。如有一条SQL语句执行的是索引扫描,我们可以使用“提示”强迫它执行全表扫描(尽管没有必要)。

1.提示的分类

有几大类的提示:

Ø 有关于优化目标的提示

Ø 有关于访问路径的提示

Ø 有关于查询转换的提示

Ø 有关于连接操作的提示

Ø 有关于连接顺序的提示

Ø 有关于并行执行的提示

2.提示的语法

提示的语法是/*+ hint(argument1 argument2) */提示/*+开始,以*/结束,中间是提示指令。argument1表示提示的第一个参数,argument2表示提示的第二个参数。当优化器遇到提示时,将按照“提示”的意图执行SQL语句。在指定提示时,如果出现错误,优化器将忽略该提示。提示中不能出现模式名。

下面的查询语句会利用到索引INDF5

SQL> SELECT * FROM T_ORDER

  2  WHERE order_name='PC';

执行计划

----------------------------------------------------------

Plan hash value: 748836800

-----------------------------------------------------------------------

| Id  | Operation                | Name    | Rows  | Bytes | Cost (%CPU)| Time|

 

-----------------------------------------------------------------------

|   0 | SELECT STATEMENT       |      |     1 |    37 |     1   (0)| 00:00:01 |

 

|   1 |  TABLE ACCESS BY INDEX ROWID| T_ORDER |  1 |    37 |     1   (0)| 00:00:01

 

|*  2 |   INDEX RANGE SCAN          | INDF5   |     1 |       |     1   (0)| 00:00:01|

SQL语句中加入提示FULL,表示要对表T_ORDER执行全表扫描。

SQL> SELECT /*+FULL(t)*/ * FROM T_ORDER t

  2  WHERE order_name='PC';

执行计划

----------------------------------------------------------

Plan hash value: 2317089884

-----------------------------------------------------------------------

| Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------

|   0 | SELECT STATEMENT  |         |     1 |    37 |     2   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T_ORDER |     1 |    37 |     2   (0)| 00:00:01 |

提示FULL改变了SQL语句的执行计划,使Oracle对表T_ORDER执行全表扫描。

3.常用提示

Oracle中,有许多提示,我们将节选部分常用的提示进行介绍。

&  ALL_ROWS

ALL_ROWS表示以吞吐量为优化目标。

SELECT /*+ALL_ROWS*/  *  FROM T_ORDER;

&  FIRST_ROWS(n)

FIRST_ROWS(n)表示选择基于开销的优化方法,以响应时间为优化目标,n表示数据行数。

SELECT /*+FIRST_ROWS**  FROM T_ORDER;

&  INDEX

该提示使Oracle执行索引扫描。

SELECT /*+ INDEX (t kt2)*/ op_no

FROM tb_user_grant t

WHERE t.menu_id like '027%';

本例使Oracle执行表tb_user_grant(别名是t)上的索引扫描,索引的名字是kt2

&  USE_MERGE

提示USE_MERGE用于指示两个表使用“排序合并连接(Sort Merge Joins)”方式进行连接(JOIN)。

SELECT  /*+ USE_MERGE(a b) */ a.op_no, a.fnm, b.menu_id, b.gwa_code, b.tr_code

FROM tb_user a, tb_user_grant b

WHERE a.op_no = b.op_no;

本例中,表tb_user(别名 a)和表 tb_user_grant(别名b)使用Sort Merge Joins方式进行连接。

&  USE_HASH

提示USE_HASH用于指示两个表使用“哈希连接(Hash Joins)”方式进行连接(JOIN)。

SELECT  /*+ USE_HASH(a b) */ a.op_no, a.fnm, b.menu_id, b.gwa_code, b.tr_code

FROM tb_user a, tb_user_grant b

WHERE a.op_no = b.op_no;

本例中,表tb_user(别名 a)和表 tb_user_grant(别名b)使用Hash Joins方式进行连接。

&  USE_NL

提示USE_NL用于指示两个表使用“嵌套循环连接(Nested Loops Join)”方式进行连接(JOIN)。

SELECT  /*+ USE_NL(a b) */ a.op_no, a.fnm, b.menu_id, b.gwa_code, b.tr_code, b.button_flg

FROM tb_user a, tb_user_grant b

WHERE a.op_no = b.op_no;

本例中,表tb_user(别名 a)和表 tb_user_grant(别名b)使用Nested Loops Join方式进行连接。

&  PARALLEL

并行执行提示的语法是:PARALLEL(表名,并行服务器进程的数量)。并行执行使Oracle启动多个并行服务器进程共同执行一条SQL语句。

SELECT  /*+ FULL(a) PARALLEL(a, 4) */ a.op_no, a.fnm

FROM tb_user a;

本例中,启动4个并行服务器进程,对表tb_user执行全表扫描。

&  PARALLEL_INDEX

索引并行执行提示的语法是:PARALLEL_INDEX(表名,索引的名字,并行服务器进程的数量)。

SELECT /*+ PARALLEL_INDEX (t,kt,3)*/ op_no

FROM tb_user_grant t

WHERE t.menu_id like '027%';

本例启动3个并行服务器进程来完成索引kt2的扫描。

 本章总结

本章重点介绍SQL语句的优化原理。在本章的实战过程中,你会遇到一些晦涩的概念,这也在情理之中。当我们遇到一些晦涩的概念时,我们可以上网或者查看Oracle的官方文档,以获得这些概念的解释,在此过程中,当你明白其中一个概念的时候,你也许也明白了其他引申的概念。在学习数据库原理时,更应该按照这种方法进行学习。

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13804621/viewspace-683182/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13804621/viewspace-683182/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值