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)