정미나닷컴
[Oracle] 오라클 스칼라 서브쿼리를 이용한 JOIN 본문
스칼라 서브쿼리
- 함수처럼 한 레코드 당 정확히 하나의 값만을 리턴하는 서브쿼리
- 주로 select-list에서 사용, 컬럼이 올 수 있는 대부분 위치에 사용 가능
SELECT EMPNO, ENAME, SAL, HIREDATE,
(SELECT D.DNAME FROM DEPT D WHERE D.DEPTNO = E.DEPTNO) DNAME
FROM EMP E
WHERE SAL >= 2000;
-- Outer JOIN과 같은 결과
-- DEPT와 JOIN에 실패하는 EMP 레코드가 있다면 DNAME으로 NULL 값 출력
스칼라 서브쿼리의 캐싱 효과
- 오라클은 스칼라 서브쿼리의 입력 값과 출력 값을 내부 캐시(Query Execution Cache)에 저장
- 스칼라 서브쿼리가 수행될 때 일단 '입력 값'을 캐시에서 찾아보고 거기 있으면 저장된 '출력 값'을 리턴
- 캐시에서 찾지 못한 경우 쿼리 수행, 결과값은 캐시에 저장
-- 반복 수행되는 함수 때문에 쿼리 성능이 크게 저하될 경우 스칼라 서브쿼리를 이용하여 튜닝
SELECT EMPNO, ENAME, SAL, HIREDATE,
(SELECT GET_DNAME(DEPTNO) FROM DUAL) DNAME
FROM EMP E
WHERE SAL >= 2000;
- 스칼라 서브쿼리의 캐싱 효과는 입력 값의 종류가 소수여서 해시 충돌 가능성이 적을 때 큼
- 입력 값의 종류가 많으면 캐시를 확인하는 비용 때문에 오히려 성능은 저하되고 CPU 사용률만 높아짐
- 버퍼 Pinning 효과X
두 개 이상의 값을 리턴하고 싶을 때
SELECT D.DEPTNO, D.DNAME, AVG_SAL, MIN_SAL, MAX_SAL
FROM DEPT D,
(SELECT DEPTNO, AVG(SAL) AVG_SAL, MIN(SAL) MIN_SAL, MAX(SAL) MAX_SAL
FROM EMP GROUP BY DEPTNO) E
WHERE D.DEPTNO = E.DEPTNO(+)
AND D.LOC = 'CHICAGO';
-- EMP 테이블 전체를 다 읽어야 하는 비효율 발생
▼
SELECT D.DEPTNO, D.DNAME,
(SELECT AVG(E1.SAL) FROM EMP E1 WHERE E1.DEPTNO = D.DEPTNO) AVG_SAL,
(SELECT MIN(E1.SAL) FROM EMP E1 WHERE E1.DEPTNO = D.DEPTNO) MIN_SAL,
(SELECT MAX(E1.SAL) FROM EMP E1 WHERE E1.DEPTNO = D.DEPTNO) MAX_SAL
FROM DEPT D
WHERE D.LOC = 'CHICAGO';
-- EMP 테이블에서 같은 범위를 반복적으로 access하는 비효율 발생
▼
SELECT DEPTNO, DNAME,
TO_NUMBER(SUBSTR(SAL, 1, 7)) AVG_SAL,
TO_NUMBER(SUBSTR(SAL, 8, 7)) MIN_SAL,
TO_NUMBER(SUBSTR(SAL, 15)) MAX_SAL
FROM (
SELECT D.DEPTNO, D.DNAME,
(SELECT LPAD(AVG(SAL), 7) || (LPAD(MIN(SAL), 7) || MAX(SAL)
FROM EMP E WHERE E.DEPTNO = D.DEPTNO) SAL
FROM DEPT D
WHERE D.LOC = 'CHICAGO'
);
'IT' 카테고리의 다른 글
[Oracle] 오라클 고급 JOIN 테크닉 - 누적 매출 구하기, 오라클 분석함수 (0) | 2017.11.04 |
---|---|
[Oracle] 오라클 JOIN을 내포한 DML 튜닝 (0) | 2017.10.29 |
[Oracle] 오라클 JOIN 순서의 중요성 (0) | 2017.10.29 |
[Oracle] 오라클 인덱스 설계 (0) | 2017.10.26 |
[Oracle] 오라클 인덱스 구조 - Bitmap Index, 비트맵 인덱스 (0) | 2017.10.22 |