iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Oracle中常见的Hint(一)
  • 346
分享到

Oracle中常见的Hint(一)

2024-04-02 19:04:59 346人浏览 泡泡鱼
摘要

oracle中的Hint可以用来调整sql的执行计划,提高SQL执行效率。下面分类介绍Oracle数据库中常见的Hint。这里描述的是Oracle11gR2中的常见Hint,Oracle数据库中各个版本中的

oracle中的Hint可以用来调整sql的执行计划,提高SQL执行效率。下面分类介绍Oracle数据库中常见的Hint。这里描述的是Oracle11gR2中的常见Hint,Oracle数据库中各个版本中的Hint都不尽相同,所以这里讲述的的Hint可能并不适用于Oracle早期的版本。

一、与优化器模式相关的Hint

1、ALL_ROWS

ALL_ROWS是针对整个目标SQL的Hint,它的含义是让优化器启用CBO,而且在得到目标SQL的执行计划时会选择那些吞吐量最佳的执行路径。这里的“吞吐量最佳”是指资源消耗量(即对I/O、CPU等硬件资源的消耗量)最小,也就是说在ALL_ROWS Hint生效的情况下,优化器会启用CBO而且会依据各个执行路径的资源消耗量来计算它们各自的成本。

ALL_ROWS Hint的格式如下:

使用范例:

select  empno,ename,sal,job
  from emp
 where empno=7396;

从Oracle10g开始,ALL_ROWS就是默认的优化器模式,启用的就是CBO。

scott@TEST>show parameter optimizer_mode

NAME				     TYPE			       VALUE
------------------------------------ --------------------------------- ------------------------------
optimizer_mode			     string			       ALL_ROWS

如果目标SQL中除了ALL_ROWS之外还使用了其他与执行路径、表连接相关的Hint,优化器会优先考虑ALL_ROWS。

2、FIRST_ROWS(n)

FIRST_ROWS(n)是针对整个目标SQL的Hint,它的含义是让优化器启用CBO模式,而且在得到目标SQL的执行计划时会选择那些能以最快的响应时间返回头n条记录的执行路径,也就是说在FIRST_ROWS(n) Hint生效的情况下,优化器会启用CBO,而且会依据返回头n条记录的响应时间来决定目标SQL的执行计划。

FIRST_ROWS(n)格式如下:

使用范例

select  empno,ename,sal,job
  from emp
 where deptno=30;

上述SQL中使用了,其含义是告诉优化器我们想以最短的响应时间返回满足条件"deptno=30"的前10条记录。

注意,FIRST_ROWS(n) Hint和优化器模式FIRST_ROWS_n不是一一对应的。优化器模式FIRST_ROWS_n中的n只能是1、10、100、1000。但FIRST_ROWS(n) Hint中的n还可以是其他值。

scott@TEST>alter session set optimizer_mode=first_rows_9;
ERROR:
ORA-00096: invalid value FIRST_ROWS_9 for parameter optimizer_mode, must be from among first_rows_1000, first_rows_100, first_rows_10, first_rows_1, first_rows, all_rows, choose,rule

scott@TEST>set autotrace traceonly
scott@TEST>select  empno from emp;

14 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 179099197

---------------------------------------------------------------------------
| Id  | Operation	 | Name   | Rows  | Bytes | Cost (%CPU)| Time	  |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |	  |	9 |    36 |	1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | PK_EMP |	9 |    36 |	1   (0)| 00:00:01 |
---------------------------------------------------------------------------

如果在UPDATE、DELETE或者含如下内容的查询语句中使用了FIRST_ROWS(n) Hint,则该Hint会被忽略:

  • 集合运算(如UNION,INTERSACT,MINUS,UNION ALL等)

  • GROUP BY 

  • FOR UPDATE

  • 聚合函数(比如SUM等)

  • DISTINCT

  • ORDER BY(对应的排序列上没有索引)

这里优化器会忽略FIRST_ROWS(n) Hint是因为对于上述类型的SQL而言,Oracle必须访问所有的行记录后才能返回满足条件的头n行记录,即在上述情况下,使用该Hint是没有意义的。

3、RULE

RULE是针对整个目标SQL的Hint,它表示对目标SQL启用RBO。

格式如下:

使用范例:

select  empno,ename,sal,job
  from emp
 where deptno=30;

RULE不能与除DRIVING_SITE以外的Hint联用,当RULE与除DRIVING_SITE以外的Hint联用时,其他Hint可能会失效;当RULE与DRIVING_SITE联用时,它自身可能会失效,所以RULE Hint最好是单独使用。

一般情况下,并不推荐使用RULE Hint。一来是因为Oracle早就不支持RBO了,二来启用RBO后优化器在执行目标SQL时可选择的执行路径将大大减少,很多执行路径RBO根本就不支持(比如哈希连接),就也就意味着启用RBO后目标SQL跑出正确执行计划的概率将大大降低。

因为很多执行路径RBO根本就不支持,所以即使在目标SQL中使用了RULE Hint,如果出现了如下这些情况(包括但不限于),RULE Hint依然会被Oracle忽略。

  • 目标SQL除RULE之外还联合使用了其他Hint(如DRIVING_SITE)。

  • 目标SQL使用了并行执行

  • 目标SQL所涉及的对象有IOT

  • 目标SQL所涉及的对象有分区表

......

二、与表访问相关的Hint

1、FULL 

FULL是针对单个目标表的Hint,它的含义是让优化器对目标表执行全表扫描。

格式如下:

使用范例:

select  empno,ename,sal,job
  from emp
 where deptno=30;

上述SQL中Hint的含义是让优化器对目标表EMP执行全表扫描操作,而不考虑走表EMP上的任何索引(即使列EMPNO上有主键索引)。

2、ROIWD

ROIWD是针对单个目标表的Hint,它的含义是让优化器对目标表执行RWOID扫描。只有目标SQL中使用了含ROWID的where条件时ROWID Hint才有意义。

格式如下:

使用范例:

select  empno,ename,sal,job
  from emp
 where rowid='AAAR3xAAEAAAACXAAA';

Oracle 11gR2中即使使用了ROWID Hint,Oracle还是会将读到的块缓存在Buffer Cache中。

三、与索引访问相关的Hint

1、INDEX

INDEX是针对单个目标表的Hint,它的含义是让优化器对目标表的的目标索引执行索引扫描操作。

INDEX Hint中的目标索引几乎可以是Oracle数据库中所有类型的索引(包括B树索引、位图索引、函数索引等)。

INDEX Hint的模式有四种:

格式1

格式2

格式3

格式4

格式1表示仅指定了目标表上的一个目标索引,此时优化器只会考虑对这个目标索引执行索引扫描操作,而不会去考虑全表扫描或者对该目标表上的其他索引执行索引扫描操作。

格式2表示指定了目标表上的n个目标索引,此时优化器只会考虑对这n个目标索引执行索引扫描操作,而不会去考虑全表扫描或者对该目标表上的其他索引执行索引扫描操作。注意,优化器在考虑这n个目标索引时,可能是分别计算出单独扫描各个目标索引的成本后,再选择其中成本值最低的索引;也可能是先分别扫描目标索引中的两个或多个索引,然后再对扫描结果执行合并操作。当然,后面这种可能性的前提条件是优化器计算出来这样做的成本值是最低的。

格式三也是表是指定了目标表上的n个目标索引,只不过此时是用指定目标索引的索引列名来代替对应的目标索引名。如果目标索引是复合索引,则在用于指定该索引列名的括号内也可以指定该目标索引的多个索引列,各个索引列之间用空格分隔就可以了。

格式的表示指定了目标表上所有已存在的索引,此时优化器只会考虑对该目标表上所有已存在的索引执行索引扫描操作,而不会去考虑全表扫描操作。注意,这里优化器在考虑该目标表上所有已存在的索引时,可能是分别计算出单独扫描这些索引的成本后再选择其中成本值最低的索引;也可能是先分别扫描这些索引中的两个或多个索引,然后再对扫描结果执行合并操作。当然,后面这种可能性的前提条件是优化器计算出来这样做的成本值是最低的。

使用范例:

select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;

2、NO_INDEX

NO_INDEX是针对单个目标表的Hint,它是INDEX的反义Hint,其含义是让优化器不对目标表上的目标索引执行扫描操作。

INDEX Hint中的目标索引也几乎可以是Oracle数据库中所有类型的索引(包括B树索引、位图索引、函数索引等)。

格式有如下三种:

格式1

格式2

格式3

格式1表示仅指定了目标表上的一个目标索引,此时优化器只是不会考虑对这个目标索引执行索引扫描操作,但还是会考虑全表扫描或者对该目标表上的其他索引执行索引扫描操作。

格式2表示指定了目标表上的n个目标索引,此时优化器只是不会考虑对这n个目标索引执行索引扫描操作,但还是会考虑全表扫描或者对该目标表上的其他索引执行索引扫描操作。

格式3表示指定了目标表上的所有已存在的索引,即此时优化器不会考虑对该目标表上所有已存在的索引执行索引扫描操作,这相当于对目标表指定了全表扫描。

使用范例:

select  empno,ename,sal,job
  from emp
where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;

3、INDEX_DESC

INDEX_DESC是针对单个目标表的Hint,它的含义是让优化器对目标表上的目标索引执行索引降序扫描操作。如果目标索引是升序的,则INDEX_DESC Hint会使Oracle以降序的方式扫描该索引;如果目标索引是降序的,则INDEX_DESC Hint会使Oracle以升序的方式扫描该索引。

格式有三种:

格式1

格式2

格式3

上述3种格式的含义和INDEX中对应格式的含义相同。

使用范例:

select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;

实例:

scott@TEST>select  empno from emp;

     EMPNO
----------
      7934
      7902
      7900
      7876
      7844
      7839
      7788
      7782
      7698
      7654
      7566
      7521
      7499
      7369

14 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1838043032

-------------------------------------------------------------------------------------
| Id  | Operation		   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	   |	    |	 10 |	 40 |	  1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN DESCENDING| PK_EMP |	 10 |	 40 |	  1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------
......

4、INDEX_COMBINE

INDEX_COMBINE是针对单个目标表的Hint,它的含义是让优化器对目标表上的多个目标索引执行位图布尔运算。Oracle数据库里有一个映射函数(Mapping Function),它可以实例B*Tree索引中的ROWID和对应位图索引中的位图之间的互相转换,所以INDEX_COMBINE Hint并不局限于位图索引,它的作用对象也可以是B*Tree索引。

格式有如下两种

格式1

格式2

格式1表示指定了目标表上的n个目标索引,此时优化器会考虑对这n个目标索引中的两个或多个执行位图布尔运算。

格式2表示指定了目标表上所有已存在的索引,此时优化器会考虑对该表上已存在的所有索引中的两个或多个执行位图布尔运算。

使用范例:

select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 ;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;
 
select  empno,ename,sal,job
  from emp
 where empno=7369 and mgr=7902 and deptno=20;

下面看一个实例,在表EMP上创建两个索引

scott@TEST>create index idx_emp_mgr on emp(mgr);

Index created.

scott@TEST>create index idx_emp_dept on emp(deptno);

Index created.

scott@TEST>select  empno,ename,sal,job
  2   from emp
  3   where empno=7369 and mgr=7902 and deptno=20;

     EMPNO ENAME				 SAL JOB
---------- ------------------------------ ---------- ---------------------------
      7369 SMITH				 800 CLERK


Execution Plan
----------------------------------------------------------
Plan hash value: 1816402415

-------------------------------------------------------------------------------------------------
| Id  | Operation			 | Name 	| Rows	| Bytes | Cost (%CPU)| Time	|
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT		 |		|     1 |    29 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID	 | EMP		|     1 |    29 |     2   (0)| 00:00:01 |
|   2 |   BITMAP CONVERSION TO ROWIDS	 |		|	|	|	     |		|
|   3 |    BITMAP AND			 |		|	|	|	     |		|
|   4 |     BITMAP CONVERSION FROM ROWIDS|		|	|	|	     |		|
|*  5 |      INDEX RANGE SCAN		 | PK_EMP	|	|	|     0   (0)| 00:00:01 |
|   6 |     BITMAP CONVERSION FROM ROWIDS|		|	|	|	     |		|
|*  7 |      INDEX RANGE SCAN		 | IDX_EMP_MGR	|	|	|     1   (0)| 00:00:01 |
|   8 |     BITMAP CONVERSION FROM ROWIDS|		|	|	|	     |		|
|*  9 |      INDEX RANGE SCAN		 | IDX_EMP_DEPT |	|	|     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
......

从上面的执行计划中可以看到关键字“BITMAP CONVERSION FROM ROWIDS”、“BITMAP AND”和“BITMAP CONVERSION TO ROWIDS”,这说明Oracle先分别对上述三个单键值的B*Tree索引IDX_EMP_MGR、IDX_EMP_DEPT和PK_EMP用映射函数将其中的ROWID转换成了位图,然后对转换后的位图执行了BITMAP AND(位图按位与)布尔运算,最后将布尔运算的结果再次用映射函数转换成了ROWID并回表得到最终的执行结果。能走出这样的执行计划显然是因为INDEX_COMBINE Hint生效了。

用映射函数将ROWID转换成了位图,然后再执行布尔运算,最后将布尔运算的结果再次用映射函数转换成了ROWID并回表得到最终的执行结果,这个过程在实际生产环境中的执行效率可能是有问题的,可以使用隐含参数_B_TREE_BITMAP_PLANS禁掉该过程中的ROWID到位图的转换:

alter session set "_b_tree_bitmap_plans"=false;

scott@TEST>alter session set "_b_tree_bitmap_plans"=false;

Session altered.

scott@TEST>select  empno,ename,sal,job
  2    from emp
  3   where empno=7369 and mgr=7902 and deptno=20;

     EMPNO ENAME				 SAL JOB
---------- ------------------------------ ---------- ---------------------------
      7369 SMITH				 800 CLERK


Execution Plan
----------------------------------------------------------
Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation		    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	    |	     |	   1 |	  29 |	   1   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP    |	   1 |	  29 |	   1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN	    | PK_EMP |	   1 |	     |	   0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
......

从上面的执行计划中可以看出没有出现BITMAP相关的关键字,即INDEX_COMBINE Hint被Oracle忽略了。

5、INDEX_FFS

INDEX_FFS是针对单个目标表的Hint,它的含义是让优化器对目标表上的目标索引执行索引快速全扫描操作。注意,索引快速全扫描能成立的前提条件是SELECT语句中所有的查询列都存在于目标索引中,即通过扫描目标索引就可以得到所有的查询列而不用回表。

格式有如下三种:

格式1

格式2

格式3

上述3种格式的含义和INDEX中对应格式的含义相同。

使用范例:

select  empno
  from emp;

select  empno
  from emp
 where mgr=7902 and deptno=20;
--create index idx_emp_1 on emp(mgr,deptno,1);
--create index idx_emp_2 on emp(mgr,deptno,2);

select  empno
  from emp;

看下面的实例:

scott@TEST>select empno from emp;

14 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 179099197

---------------------------------------------------------------------------
| Id  | Operation	 | Name   | Rows  | Bytes | Cost (%CPU)| Time	  |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |	  |    10 |    40 |	1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | PK_EMP |    10 |    40 |	1   (0)| 00:00:01 |
---------------------------------------------------------------------------
......
scott@TEST>select empno from emp;

14 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 366039554

-------------------------------------------------------------------------------
| Id  | Operation	     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |	      |    10 |    40 |     2	(0)| 00:00:01 |
|   1 |  INDEX FAST FULL SCAN| PK_EMP |    10 |    40 |     2	(0)| 00:00:01 |
-------------------------------------------------------------------------------
......

6、INDEX_JOIN

INDEX_JOIN是针对单个目标表的Hint,它的含义是让优化器对目标表上的多个目标索引执行INDEX JOIN操作。INDEX JOIN能成立的前提条件是SELECT语句中所有的查询列都存在于目标表上的多个目标索引中,即通过扫描这些索引就可以得到所有的查询列而不用回表。

格式如下:

格式1

格式2

上述两种格式的含义与INDEX_COMBINE Hint中对应格式的含义相同。

使用范例:

select  empno,mgr
  from emp
 where empno>7369 and mgr<7902;
 
select  empno,mgr
  from emp
 where empno>7369 and mgr<7902;

来看下面的实例:

scott@TEST>select empno,mgr
  2    from emp
  3   where empno>7369 and mgr<7902;

12 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2059184959

-------------------------------------------------------------------------------------------
| Id  | Operation		    | Name	  | Rows  | Bytes | Cost (%CPU)| Time	  |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	    |		  |    10 |    80 |	2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP	  |    10 |    80 |	2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN	    | IDX_EMP_MGR |    11 |	  |	1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
......
scott@TEST>select  empno,mgr
  2    from emp
  3   where empno>7369 and mgr<7902;

12 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3030719951

---------------------------------------------------------------------------------------
| Id  | Operation	   | Name	      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |		      |    10 |    80 |     3  (34)| 00:00:01 |
|*  1 |  VIEW		   | index$_join$_001 |    10 |    80 |     3  (34)| 00:00:01 |
|*  2 |   HASH JOIN	   |		      |       |       | 	   |	      |
|*  3 |    INDEX RANGE SCAN| IDX_EMP_MGR      |    10 |    80 |     2  (50)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN| PK_EMP	      |    10 |    80 |     2  (50)| 00:00:01 |
---------------------------------------------------------------------------------------
......

7、AND_EQUAL

AND_EQUAL是针对单个目标表的Hint,它的含义是让优化器对目标表上的多个目标索引执行INDEX MERGE操作。INDEX MERGE能成立的前提条件是目标SQL的where条件里出现了多个针对不同单列的等值条件,并且这些列上都有单键值的索引。另外,在Oracle数据库里,能够做INDEX MERGE的索引数量的最大值是5。

格式如下:

使用范例:

select  empno,mgr
  from emp
 where deptno=20 and mgr=7902;

看下面的实例:

scott@TEST>select empno,mgr
  2    from emp
  3   where deptno=20 and mgr=7902;


Execution Plan
----------------------------------------------------------
Plan hash value: 2059184959

-------------------------------------------------------------------------------------------
| Id  | Operation		    | Name	  | Rows  | Bytes | Cost (%CPU)| Time	  |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	    |		  |	1 |    11 |	2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP	  |	1 |    11 |	2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN	    | IDX_EMP_MGR |	2 |	  |	1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
......
scott@TEST>select  empno,mgr
  2    from emp
  3   where deptno=20 and mgr=7902;


Execution Plan
----------------------------------------------------------
Plan hash value: 3295440569

--------------------------------------------------------------------------------------------
| Id  | Operation		    | Name	   | Rows  | Bytes | Cost (%CPU)| Time	   |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	    |		   |	 1 |	11 |	 3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP	   |	 1 |	11 |	 3   (0)| 00:00:01 |
|   2 |   AND-EQUAL		    |		   |	   |	   |		|	   |
|*  3 |    INDEX RANGE SCAN	    | IDX_EMP_MGR  |	 2 |	   |	 1   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN	    | IDX_EMP_DEPT |	 5 |	   |	 1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
......

四、与表连接顺序相关的Hint

1、ORDERED

ORDERED是针对多个目标表的Hint,它的含义是让优化器对多个目标表执行表连接操作时,执照它们在目标SQL的where条件中出现的顺序从左到右依次进行连接。

格式如下:

使用范例:

select  e.ename,j.job,e.sal,d.deptno
  from emp e,jobs j,dept d 
 where e.empno=j.empno
   and e.deptno=d.deptno
   and d.loc='CHICAGo'
 order by e.ename;

实例:

scott@TEST>select e.ename,j.job,e.sal,d.deptno
  2    from emp e,jobs j,dept d 
  3   where e.empno=j.empno
  4     and e.deptno=d.deptno
  5     and d.loc='CHICAGO'
  6   order by e.ename;

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4113290228

-----------------------------------------------------------------------------------------------
| Id  | Operation                      | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |              |     5 |   235 |     9  (23)| 00:00:01 |
|   1 |  SORT ORDER BY                 |              |     5 |   235 |     9  (23)| 00:00:01 |
|*  2 |   HASH JOIN                    |              |     5 |   235 |     8  (13)| 00:00:01 |
|   3 |    NESTED LOOPS                |              |       |       |            |          |
|   4 |     NESTED LOOPS               |              |     5 |   140 |     4   (0)| 00:00:01 |
|*  5 |      TABLE ACCESS FULL         | DEPT         |     1 |    11 |     3   (0)| 00:00:01 |
|*  6 |      INDEX RANGE SCAN          | IDX_EMP_DEPT |     5 |       |     0   (0)| 00:00:01 |
|   7 |     TABLE ACCESS BY INDEX ROWID| EMP          |     5 |    85 |     1   (0)| 00:00:01 |
|   8 |    TABLE ACCESS FULL           | JOBS         |    14 |   266 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
......
scott@TEST>select  e.ename,j.job,e.sal,d.deptno
  2    from emp e,jobs j,dept d 
  3   where e.empno=j.empno
  4     and e.deptno=d.deptno
  5     and d.loc='CHICAGO'
  6   order by e.ename;

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3031293267

-----------------------------------------------------------------------------------------
| Id  | Operation                      | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |        |     5 |   235 |    11  (28)| 00:00:01 |
|   1 |  SORT ORDER BY                 |        |     5 |   235 |    11  (28)| 00:00:01 |
|*  2 |   HASH JOIN                    |        |     5 |   235 |    10  (20)| 00:00:01 |
|   3 |    MERGE JOIN                  |        |    14 |   504 |     6  (17)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| EMP    |    14 |   238 |     2   (0)| 00:00:01 |
|   5 |      INDEX FULL SCAN           | PK_EMP |    14 |       |     1   (0)| 00:00:01 |
|*  6 |     SORT JOIN                  |        |    14 |   266 |     4  (25)| 00:00:01 |
|   7 |      TABLE ACCESS FULL         | JOBS   |    14 |   266 |     3   (0)| 00:00:01 |
|*  8 |    TABLE ACCESS FULL           | DEPT   |     1 |    11 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
......
scott@TEST>select  e.ename,j.job,e.sal,d.deptno
  2    from emp e,dept d,jobs j
  3   where e.empno=j.empno
  4     and e.deptno=d.deptno
  5     and d.loc='CHICAGO'
  6   order by e.ename;

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1175157407

-----------------------------------------------------------------------------------------------
| Id  | Operation                      | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |              |     5 |   235 |    11  (28)| 00:00:01 |
|   1 |  SORT ORDER BY                 |              |     5 |   235 |    11  (28)| 00:00:01 |
|*  2 |   HASH JOIN                    |              |     5 |   235 |    10  (20)| 00:00:01 |
|   3 |    MERGE JOIN                  |              |     5 |   140 |     6  (17)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| EMP          |    14 |   238 |     2   (0)| 00:00:01 |
|   5 |      INDEX FULL SCAN           | IDX_EMP_DEPT |    14 |       |     1   (0)| 00:00:01 |
|*  6 |     SORT JOIN                  |              |     1 |    11 |     4  (25)| 00:00:01 |
|*  7 |      TABLE ACCESS FULL         | DEPT         |     1 |    11 |     3   (0)| 00:00:01 |
|   8 |    TABLE ACCESS FULL           | JOBS         |    14 |   266 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
......

从上面的执行计划可以看出不使用ordered Hint时表扫描的顺序是DEPT->EMP->JOBS,但是使用ordered Hint后,表扫描的顺序变为了EMP->JOBS->DEPT与目标SQL中的顺序一致了,在修改了目标SQL文本之后表的扫描顺序也相应地变为了EMP->DEPT->JOBS。

2、LEADING

LEADING是针对多个目标表的Hint,它的含义是让优化器将我们指定的多个表的连接结果作为目标SQL表连接过程中的驱动结果集,并且将LEADING Hint中从左至右出现的第一个目标表作为整个表连接过程中的首个驱动表。

LEADING比ORDERED要温和一些,因为它只是指定了首个驱动表和驱动结果集,没有像ORDERED那样完全指定了表连接的顺序,也就是说LEADING给了优化器更大的调整余地。

当LEADING Hint中指定的表并不能作为目标SQL的连接过程中的驱动表或者驱动结果集时,Oracle会忽略该Hint。

格式如下:

使用范例:

select  e.ename,j.job,e.sal,d.deptno
  from emp e,jobs j,dept d,emp_temp t 
 where e.empno=j.empno
   and e.deptno=d.deptno
   and d.loc='CHICAGO'
   and e.ename=t.ename
 order by e.ename;

实例:

--不使用Hint
scott@TEST>select e.ename,j.job,e.sal,d.deptno
  2    from emp e,jobs j,dept d,emp_temp t 
  3   where e.empno=j.empno
  4     and e.deptno=d.deptno
  5     and d.loc='CHICAGO'
  6     and e.ename=t.ename
  7   order by e.ename;

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 558051962

------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |              |     5 |   270 |    12  (17)| 00:00:01 |
|   1 |  SORT ORDER BY                  |              |     5 |   270 |    12  (17)| 00:00:01 |
|*  2 |   HASH JOIN                     |              |     5 |   270 |    11  (10)| 00:00:01 |
|*  3 |    HASH JOIN                    |              |     5 |   235 |     8  (13)| 00:00:01 |
|   4 |     NESTED LOOPS                |              |       |       |            |          |
|   5 |      NESTED LOOPS               |              |     5 |   140 |     4   (0)| 00:00:01 |
|*  6 |       TABLE ACCESS FULL         | DEPT         |     1 |    11 |     3   (0)| 00:00:01 |
|*  7 |       INDEX RANGE SCAN          | IDX_EMP_DEPT |     5 |       |     0   (0)| 00:00:01 |
|   8 |      TABLE ACCESS BY INDEX ROWID| EMP          |     5 |    85 |     1   (0)| 00:00:01 |
|   9 |     TABLE ACCESS FULL           | JOBS         |    14 |   266 |     3   (0)| 00:00:01 |
|  10 |    TABLE ACCESS FULL            | EMP_TEMP     |    14 |    98 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
......
--使用LEADING Hint
scott@TEST>select  e.ename,j.job,e.sal,d.deptno
  2    from emp e,jobs j,dept d,emp_temp t 
  3   where e.empno=j.empno
  4     and e.deptno=d.deptno
  5     and d.loc='CHICAGO'
  6     and e.ename=t.ename
  7   order by e.ename;

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 937897748

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     5 |   270 |    15  (20)| 00:00:01 |
|   1 |  SORT ORDER BY        |          |     5 |   270 |    15  (20)| 00:00:01 |
|*  2 |   HASH JOIN           |          |     5 |   270 |    14  (15)| 00:00:01 |
|*  3 |    HASH JOIN          |          |     5 |   175 |    10  (10)| 00:00:01 |
|*  4 |     HASH JOIN         |          |    14 |   336 |     7  (15)| 00:00:01 |
|   5 |      TABLE ACCESS FULL| EMP_TEMP |    14 |    98 |     3   (0)| 00:00:01 |
|   6 |      TABLE ACCESS FULL| EMP      |    14 |   238 |     3   (0)| 00:00:01 |
|*  7 |     TABLE ACCESS FULL | DEPT     |     1 |    11 |     3   (0)| 00:00:01 |
|   8 |    TABLE ACCESS FULL  | JOBS     |    14 |   266 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------
......
--使用Ordered Hint
scott@TEST>select  e.ename,j.job,e.sal,d.deptno
  2    from emp e,jobs j,dept d,emp_temp t 
  3   where e.empno=j.empno
  4     and e.deptno=d.deptno
  5     and d.loc='CHICAGO'
  6     and e.ename=t.ename
  7   order by e.ename;

6 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2459794491

--------------------------------------------------------------------------------------------
| Id  | Operation                       | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |          |     5 |   270 |    14  (22)| 00:00:01 |
|   1 |  SORT ORDER BY                  |          |     5 |   270 |    14  (22)| 00:00:01 |
|*  2 |   HASH JOIN                     |          |     5 |   270 |    13  (16)| 00:00:01 |
|*  3 |    HASH JOIN                    |          |     5 |   235 |    10  (20)| 00:00:01 |
|   4 |     MERGE JOIN                  |          |    14 |   504 |     6  (17)| 00:00:01 |
|   5 |      TABLE ACCESS BY INDEX ROWID| EMP      |    14 |   238 |     2   (0)| 00:00:01 |
|   6 |       INDEX FULL SCAN           | PK_EMP   |    14 |       |     1   (0)| 00:00:01 |
|*  7 |      SORT JOIN                  |          |    14 |   266 |     4  (25)| 00:00:01 |
|   8 |       TABLE ACCESS FULL         | JOBS     |    14 |   266 |     3   (0)| 00:00:01 |
|*  9 |     TABLE ACCESS FULL           | DEPT     |     1 |    11 |     3   (0)| 00:00:01 |
|  10 |    TABLE ACCESS FULL            | EMP_TEMP |    14 |    98 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
......

从上面的执行计划可以看出不使用Hint时表扫描顺序是DEPT->EMP->JOBS->EMP_TEMP;使用LEADING Hint时表扫描顺序是EMP_TEMP->EMP->DEPT->JOBS,EMP_TEMP做首个驱动表和表EMP的连接结果做为驱动结果集,与Hint要求一致。;使用Ordered Hint时表扫描顺序是EMP->JOBS->DEPT->EMP_TEMP,与SQL中顺序一致。


参考《基于Oracle的SQL优化》

官方文档:Http://docs.oracle.com/cd/E11882_01/server.112/e41573/hintsref.htm#PFGRF005



您可能感兴趣的文档:

--结束END--

本文标题: Oracle中常见的Hint(一)

本文链接: https://www.lsjlt.com/news/35757.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle常见hint
    与优化器模式相关的hint...
    99+
    2024-04-02
  • oracle常用hint是怎样的
    oracle常用hint是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 1. 希...
    99+
    2024-04-02
  • ORACLE中的的HINT详解
    在ORACLE数据库中,HINT是一种特殊的注释语法,可以在SQL语句中指定查询优化器在执行查询时使用特定的执行计划。HINT可以用来影响查询语句的执行计划,以提高查询性能。HINT语法如下:其中,hint_name是具体的HINT名称...
    99+
    2023-08-11
    Oracle
  • oracle中hint的作用是什么
    在Oracle中,Hint是一种指令,用于告诉查询优化器如何执行查询。它可以用来指导查询优化器选择特定的执行计划,以提高查询性能。 ...
    99+
    2024-04-09
    oracle
  • oracle中hint的用法是什么
    在Oracle数据库中,可以使用Hint来影响查询优化器的执行计划,以达到更好的性能。Hint是一种特殊的注释形式,可以用来提示优化...
    99+
    2024-03-11
    oracle
  • oracle中常见的约束有哪些
    oracle中的常见约束通过特定规则维护数据完整性和一致性。这些约束包括:1. 主键约束:确保每行都有唯一id。2. 外键约束:将表中的列与另一个表中的列关联。3. 唯一约束:保证列值唯...
    99+
    2024-05-09
    oracle
  • oracle中hint的优点和缺点是什么
    在Oracle数据库中,使用hint可以对查询语句进行优化调整,以达到更好的性能和执行计划。然而,使用hint也存在一些缺点。 优点...
    99+
    2024-04-09
    oracle
  • oracle hint的用法是什么
    Oracle的Hint是一种在SQL语句中使用的指令,可以用来指导Oracle数据库查询优化器执行查询操作时的决策。通过使用Hint...
    99+
    2024-04-09
    oracle
  • linux中oracle常见命令有哪些
    这篇文章将为大家详细讲解有关linux中oracle常见命令有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。关于“linux中oracle常见命令有哪些”这篇文章就分...
    99+
    2024-04-02
  • go中make用法及常见的一些坑
    目录make用法和参数用法使用make常见的一些坑1:slice使用make2:map使用map:总结make用法和参数用法 golang分配内存有一个make函数,该函数第一个数类...
    99+
    2022-12-26
    go语言make go语言make
  • React中refs的一些常见用法汇总
    目录什么是Refs 一、String 类型的 Refs 二、回调 Refs三、React.createRef()四、useRef五、Refs 与函数组件总结什么是Refs Refs...
    99+
    2024-04-02
  • 聊聊javascript中常见的一些转义字符
    JavaScript是一种基于文本的编程语言,因此它需要一种机制来处理特殊字符。这些特殊字符可以是控制字符,例如换行符和制表符,或者是一些需要转义的字符,例如引号和反斜杠。在JavaScript中,使用反斜杠(\)来指示特殊字符。这被称为转...
    99+
    2023-05-14
  • python中字符串的常见操作总结(一)
    目录前言python中的对象什么是对象?字符串的capitalize()函数capitalize()的功能capitalize()的用法字符串的小写内置函数字符串的upper()函数...
    99+
    2024-04-02
  • python3--中一些常见的坑(机制上的问题)
    python中is,==,id 的意思== :数值的比较is :内存地址的比较id :查看内存地址list(列表)中存在的一些坑重点:在循环一个列表时,最好不要进行删除的动作(一旦删除,索引会随之改变),容易错误。将下面列表中索引为奇数的元...
    99+
    2023-01-30
    机制 常见
  • 一文总结JavaScript中常见的设计模式
    目录设计原则什么是设计模式一、单例模式二、策略模式三、代理模式四、迭代器模式五、发布-订阅模式六、命令模式七、组合模式八、模板方法模式九、享元模式十、职责链模式十一、中介者模式十二、...
    99+
    2023-05-19
    JavaScript设计模式 JavaScript设计
  • 总结一些html开发中常见的错误
    很多人都曾经遇到过编写网页时出现HTML代码错误的情况,这种错误如果不及时处理,会导致网页无法正常显示或出现其它问题,给用户带来不良体验。因此,在编写HTML代码时,我们需要注意一些常见的错误,并及时进行修复。首先,常见的HTML代码错误包...
    99+
    2023-05-14
  • python列表中常见的一些排序方法
    目录1、冒泡排序法方法一:直接使用for循环方法二:使用while语句2、选择排序法方法一:remove和append同时使用方法二:pop和append同时使用3、list.sor...
    99+
    2024-04-02
  • sql中hint的用法是什么
    在SQL中,hint用于告诉数据库优化器如何执行查询,以提高查询性能。hint是一种注释语法,用于提示数据库优化器如何执行查询,以确...
    99+
    2024-03-11
    sql
  • Docker中常见的异常总结
    本篇内容主要讲解“Docker中常见的异常总结”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Docker中常见的异常总结”吧!异常一docker ps 无响应, Node 节点表现为 NotRe...
    99+
    2023-06-19
  • Oracle 中常见的日志类型及配置方法
    Oracle 中常见的日志类型及配置方法 Oracle 数据库是业界领先的关系型数据库管理系统之一,它提供了丰富的日志类型来记录数据库的操作和性能信息。在实际的数据库管理工作中,了解并...
    99+
    2024-03-09
    oracle 配置 日志
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作