h3.(1) 스칼라 서브쿼리
서브쿼리 : 쿼리에 내장된 또다른 쿼리 블록
스칼라 서브쿼리 : 함수처럼 한 레코드당 정확히 하나의 값만을 리턴하는 서브쿼리
h3.(2) 스칼라 서브쿼리의 캐싱효과
select empno, ename, sal, hiredate
, (select d.dname -> 출력값 : d.dname
from dept d
where d.deptno = e.empno -> 입력값 : e.empno
)
from emp e
where sal >= 2000;
EMPNO ENAME SAL HIREDATE (SELECTD.DNAME
---------- ---------- ---------- -------- --------------
7566 JONES 2975 81/04/02
7698 BLAKE 2850 81/05/01
7782 CLARK 2450 81/06/09
7788 SCOTT 3000 87/03/20
7839 KING 5000 81/11/17
7902 FORD 3000 81/12/03
6 개의 행이 선택되었습니다.
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 242 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 13 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | EMP | 11 | 242 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("D"."DEPTNO"=:B1)
3 - filter("SAL">=2000)
결론 : 스칼라 서브쿼리는 입력값의 종류가 소수여야 해시 충돌이 적어 효과 적이다.
반대의 경우에 캐시 확인 비용으로 인하여 성능은 저하되고 CPU 사용은 높게 된다.
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 where deptno=d.deptno) sal
from dept d
where d.loc='CHICAGO'
);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
|* 2 | TABLE ACCESS FULL| EMP | 1 | 26 | 3 (0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 26 | | |
|* 4 | TABLE ACCESS FULL| EMP | 1 | 26 | 3 (0)| 00:00:01 |
| 5 | SORT AGGREGATE | | 1 | 26 | | |
|* 6 | TABLE ACCESS FULL| EMP | 1 | 26 | 3 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | DEPT | 1 | 30 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("DEPTNO"=:B1)
4 - filter("DEPTNO"=:B1)
6 - filter("DEPTNO"=:B1)
7 - filter("D"."LOC"='CHICAGO')
Note
-----
- dynamic sampling used for this statement
create or replace type sal_type as object
(avg_sal number, min_sal number, max_sal number)
/
select deptno, dname
, a.sal.avg_sal, a.sal.min_sal ,a.sal.max_sal
from
(
select d.deptno, d.dname
, (select sal_type(avg(sal), min(sal), max(sal))
from emp where deptno=d.deptno) sal
from dept d
where d.loc='CHICAGO'
) a ;
DEPTNO DNAME SAL.AVG_SAL SAL.MIN_SAL SAL.MAX_SAL
---------- -------------- ----------- ----------- -----------
30 SALES 1566.66667 950 2850
Execution Plan
----------------------------------------------------------
Plan hash value: 2018188441
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
|* 2 | TABLE ACCESS FULL| EMP | 1 | 26 | 3 (0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 26 | | |
|* 4 | TABLE ACCESS FULL| EMP | 1 | 26 | 3 (0)| 00:00:01 |
| 5 | SORT AGGREGATE | | 1 | 26 | | |
|* 6 | TABLE ACCESS FULL| EMP | 1 | 26 | 3 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | DEPT | 1 | 30 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("DEPTNO"=:B1)
4 - filter("DEPTNO"=:B1)
6 - filter("DEPTNO"=:B1)
7 - filter("D"."LOC"='CHICAGO')
Note
-----
- dynamic sampling used for this statement