조건절을 View 내부로 이동시켜라
FPD는 View 또는 Inline View의 Outer에서 View Column을 참조한 조건절을 사용 시, 이 조건절이 View 내부로 들어가는 기법을 말한다.
예제 Query
oracle>
SELECT a.employee_id,
a.first_name,
a.last_name,
a.email,
b.department_name
FROM ( SELECT /*+ NO_MERGE */
employee_id,
first_name,
last_name,
job_id,
email,
department_id
FROM employees ) a,
departments b
WHERE a.department_id = b.department_id
AND a.job_id = 'MK_REF';
PLAN
Execution Plan
----------------------------------------------------------
Plan hash value: 546572834
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 96 | 2 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 1 | 96 | 2 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 1 | 96 | 2 (0)| 00:00:01 |
| 3 | VIEW | | 1 | 66 | 2 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL | EMPLOYEES | 1 | 73 | 2 (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 | 30 | 0 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("JOB_ID"='MK_REF')
5 - access("A"."DEPARTMENT_ID"="B"."DEPARTMENT_ID")
Predicate Information을 살펴보면 조건절의 filter가 4번에 위치하는 것을 확인할 수 있다. 4번은 View 안쪽 있는 Table에 대한 Full Scan을 의미한다. 따라서, filter가 4번에 관련된 정보인 것을 보면 FPD가 발생한 것으로 보인다.
Rewrte Query
Plan을 기반으로 생각하면, Optimizer는 아래와 같이 Query를 변경한 것이다.
SELECT a.employee_id,
a.first_name,
a.last_name,
a.email,
b.department_name
FROM ( SELECT /*+ NO_MERGE */
employee_id,
first_name,
last_name,
job_id,
email,
department_id
FROM employees
WHERE job_id = 'MK_REF' ) a,
departments b
WHERE a.department_id = b.department_id;