View를 사용하면 코드 유지보수성은 좋아질 수 있으나 성능관점에서는 결과가 안좋을 수 있다. 아래 예시를 살펴보자.
Employees 테이블
| NO | EMPLOYEE_ID | FIRST_NAME | LAST_NAME | DEPARTMENT_ID | |
| 1 | 198 | Donald | OConnell | DOCONNEL | 50 |
| 2 | 199 | Douglas | Grant | DGRANT | 50 |
| 3 | 200 | Jennifer | Whalen | JWHALEN | 10 |
Departments 테이블
| NO | DEPARTMENT_ID | DEPARTMENT_NAME | MANAGER_ID | LOCATION_ID |
| 1 | 10 | Administration | 200 | 1700 |
| 2 | 20 | Marketing | 201 | 1800 |
| 3 | 30 | Purchasing | 114 | 1700 |
Locations 테이블
| NO | LOCATION_ID | STREET_ADDRESS | POSTAL_CODE | CITY |
| 1 | 1000 | 1297 Via Cola di Rie | 00989 | Roma |
| 2 | 1100 | 93091 Calle della Testa | 10934 | Venice |
| 3 | 1200 | 2017 Shinjuku-ku | 1689 | Tokyo |
아래와 같이 View를 생성하였다.
CREATE OR REPLACE VIEW VW_EMP_DEPT AS
SELECT E.EMPLOYEE_ID, E.LAST_NAME, E.FIRST_NAME, E.SALARY, E.JOB_ID,
D.DEPARTMENT_ID, D.DEPARTMENT_NAME, D.LOCATION_ID, L.STATE_PROVINCE
FROM EMPLOYEES E, DEPARTMENTS D , LOCATIONS L
WHERE E.DEPARTMENT_ID(+) = D.DEPARTMENT_ID
AND D.LOCATION_ID = L.LOCATION_ID;
아래와 같이 View와 Join하여 쿼리를 수행하였을때 Execution Plan을 보면 아래와 같이 Departments 테이블 관련 컬럼은 조회하지 않으나 수행 계획에는 표시됨을 볼 수 있다.
SELECT V.FIRST_NAME, V.LAST_NAME, J.JOB_TITLE
FROM JOBS J, VW_EMP_DEPT V
WHERE J.JOB_ID = 'IT_PROG'
AND V.JOB_ID = J.JOB_ID;

다음 View를 보자
CREATE OR REPLACE VIEW VW_CUST_NUM_SOLD AS
SELECT C.CUST_ID, CUST_FIRST_NAME,CUST_LAST_NAME, PROD_ID, COUNT(*) NUM_SOLD
FROM SALES S, CUSTOMERS C
WHERE S.CUST_ID = C.CUST_ID
GROUP BY C.CUST_ID,CUST_FIRST_NAME, CUST_LAST_NAME, PROD_ID
ORDER BY NUM_SOLD DESC;
다음 쿼리를 실행해보면 View 내부에 Predicate가 잘 들어가 있는 것을 볼 수있다.
SELECT CUST_ID,PROD_NAME,NUM_SOLD
FROM VW_CUST_NUM_SOLD V, PRODUCTS P
WHERE V.PROD_ID = P.PROD_ID
AND V.PROD_ID = 13;
Predicate 잘 들어가 있고 총 Cost 447이 나왔다.

위와 같은 결과 인데 View 기준으로 Outer Join을 하면 어떻게 될까?
SELECT CUST_ID,PROD_NAME,NUM_SOLD
FROM VW_CUST_NUM_SOLD V, PRODUCTS P
WHERE V.PROD_ID = P.PROD_ID(+)
AND V.PROD_ID = 13;
Customer Table 의 경우 index, predicate없이 full 스캔이 되어버렸다. 총 Cost는 769로 엄청 늘었다.

동일한 결과를 위해 View를 사용하지 않고 직접 쿼리를 구성하면 어떻게 될까?
SELECT C.CUST_ID, P.PROD_NAME, COUNT(*) NUM_SOLD FROM SALES S, CUSTOMERS C, PRODUCTS P
WHERE S.CUST_ID = C.CUST_ID
AND S.PROD_ID = P.PROD_ID(+)
AND P.PROD_ID = 13
GROUP BY C.CUST_ID, P.PROD_NAME
ORDER BY NUM_SOLD DESC;
Customer table에 대해서 index조회가 잘 되어서 Outer Join을 수행해도 결과가 Cost 364로 양호하다.

-- The End --
'Database > Oracle' 카테고리의 다른 글
| [Oracle] 오라클 서브쿼리 종류 (0) | 2025.11.21 |
|---|---|
| [Oracle] Partition by로 그룹별 순서기반으로 집계하기 (0) | 2025.11.20 |
| [Oracle] Oracle Join 종류 정리 #2 (0) | 2025.11.05 |
| [Oracle] and system_cd(+) = 'COM' 과 같이 상수값 비교 조건에도 (+)가 붙는 이유 (0) | 2025.11.05 |
| [Oracle] Oracle Join 종류 정리 (0) | 2025.11.05 |