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)