首页 > Linux操作系统 > Linux操作系统 > 构筑高速运行的SQL语句(五)
提示(Hint)是嵌入到SQL语句中的一些指令,用于改变SQL语句的执行计划。如有一条SQL语句执行的是索引扫描,我们可以使用“提示”强迫它执行全表扫描(尽管没有必要)。
有几大类的提示:
Ø 有关于优化目标的提示
Ø 有关于访问路径的提示
Ø 有关于查询转换的提示
Ø 有关于连接操作的提示
Ø 有关于连接顺序的提示
Ø 有关于并行执行的提示
提示的语法是/*+ 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执行全表扫描。
在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博客 ” ,链接:https://blog.itpub.net/13804621/viewspace-683182/ ,如需转载,请注明出处,否则将追究法律责任。