驱动表问题

NL改变内链接驱动表:

SQL> select e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id
and e.department_id=10;
  2    3    4  

Execution Plan
----------------------------------------------------------
Plan hash value: 1323567469

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     2   (0)| 00:00:01 |
|   1 |  NESTED LOOPS		     |			 |     1 |    27 |     2   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     1   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("D"."DEPARTMENT_ID"=10)
   5 - access("E"."DEPARTMENT_ID"=10


此时的驱动表为DEPARTMENTS
修改NL 驱动表的顺序
SQL> select /*+leading(e) use_nl(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id
and e.department_id=10;
  2    3    4  

Execution Plan
----------------------------------------------------------
Plan hash value: 2599337293

---------------------------------------------------------------------------------------------------
| Id  | Operation		      | Name		  | Rows  | Bytes | Cost (%CPU)| Time	  |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	      | 		  |	1 |    27 |	3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS		      | 		  |	  |	  |	       |	  |
|   2 |   NESTED LOOPS		      | 		  |	1 |    27 |	3   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| EMPLOYEES	  |	1 |    11 |	2   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN	      | EMP_DEPARTMENT_IX |	1 |	  |	1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN	      | DEPT_ID_PK	  |	1 |	  |	0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID | DEPARTMENTS	  |	1 |    16 |	1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("E"."DEPARTMENT_ID"=10)
   5 - access("D"."DEPARTMENT_ID"=10)

此时驱动表为EMPLOYEES 

外链接呢?
SQL> select  /*+use_nl(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id(+)
and e.department_id=10;
  2    3    4  

Execution Plan
----------------------------------------------------------
Plan hash value: 4166763565

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER	     |			 |     1 |    27 |     3   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("E"."DEPARTMENT_ID"=10)
   5 - access("D"."DEPARTMENT_ID"(+)=10)

次数驱动表为 EMPLOYEES,NL外链接能修改驱动表吗?

SQL> select  /*+leading(d) use_nl(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id(+)
and e.department_id=10;
  2    3    4  

Execution Plan
----------------------------------------------------------
Plan hash value: 4166763565

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER	     |			 |     1 |    27 |     3   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("E"."DEPARTMENT_ID"=10)
   5 - access("D"."DEPARTMENT_ID"(+)=10)

强制d为驱动表,但是驱动表依旧是EMPLOYEES

那么HASH JOIN呢?
SQL> select  /*+use_hash(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id
and e.department_id=10;  2    3    4  


Execution Plan
----------------------------------------------------------
Plan hash value: 2281705064

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|*  1 |  HASH JOIN		     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     2   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
   3 - access("D"."DEPARTMENT_ID"=10)
   5 - access("E"."DEPARTMENT_ID"=10)

此时驱动表为DEPARTMENTS,那么怎么改变驱动表顺序呢,使用hint是swap_join_inputs

SQL> select  /*+swap_join_inputs(e) use_hash(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id
and e.department_id=10;  2    3    4  


Execution Plan
----------------------------------------------------------
Plan hash value: 2474857051

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|*  1 |  HASH JOIN		     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
   3 - access("E"."DEPARTMENT_ID"=10)
   5 - access("D"."DEPARTMENT_ID"=10)

此时驱动表变为EMPLOYEES

那么HASH JOIN在外链接的情况呢?
SQL> select  /*+use_hash(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id(+)
and e.department_id=10;
  2    3    4  

Execution Plan
----------------------------------------------------------
Plan hash value: 3327035364

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|*  1 |  HASH JOIN OUTER	     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID"(+))
   3 - access("E"."DEPARTMENT_ID"=10)
   5 - access("D"."DEPARTMENT_ID"(+)=10)

此时驱动表是EMPLOYEES,如何改变呢?
SQL> select  /*+swap_join_inputs(d) use_hash(e d)*/ e.last_name, e.department_id, d.department_name
  from employees e, departments d
 where e.department_id = d.department_id(+)
and e.department_id=10;
  2    3    4  

Execution Plan
----------------------------------------------------------
Plan hash value: 2375739685

--------------------------------------------------------------------------------------------------
| Id  | Operation		     | Name		 | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT	     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT OUTER	     |			 |     1 |    27 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| DEPARTMENTS	 |     1 |    16 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN	     | DEPT_ID_PK	 |     1 |	 |     0   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| EMPLOYEES	 |     1 |    11 |     2   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN	     | EMP_DEPARTMENT_IX |     1 |	 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID"(+))
   3 - access("D"."DEPARTMENT_ID"(+)=10)
   5 - access("E"."DEPARTMENT_ID"=10)

原文地址:https://www.cnblogs.com/zhaoyangjian724/p/3798059.html