다음과 같이 EMP
테이블에서 10번 부서의 입사일이 가장 최근인 사람과 같은 입사일을 가진 사원의 사번과 급여를 출력하는 예를
생각해보자. 보통 다음과 같은 SQL문을 이용할
것이다.
:namespace prefix = o ns =
"urn:schemas-microsoft-com:office:office" />
SQL> select ename, sal
2
from emp
3
where hiredate = (select max(hiredate)
4 from
emp
5 where deptno =
10);
ENAME SAL
----------
----------
MILLER 1300
위의 경우 서브쿼리를 해서 테이블을
두 번 액세스하게 된다. 또한 이 SQL 문은 서브쿼리가 독립적으로 먼저 풀려서 상수가 되므로
결국 HIREDATE = 상수 조건이 되어 이 조건에 맞는 여러 건의 로우가 리턴 된다.
SQL> select max(hiredate)
2
from emp
3
where deptno = 10;
MAX(HIRE
--------
82/01/23
예를 들어 서브쿼리에서
나온 MAX(HIREDATE)의 값이 '82/01/23' 이었다면 최종 풀리는 SQL 문은 SELECT ENAME, SAL
FROM EMP WHERE HIREDATE = ‘82/01/23’ 과 같이 풀려서 여러 건의 로우가 같이 나오게
된다.
이번에는 역순 인덱스를 이용한 힌트를
이용해 보도록 하자.
SQL> create index
idx_emp_hiredate on emp(hiredate);
SQL> select
2 ename,
sal
3 from
emp
4 where deptno =
10
5 and hiredate is not
null
6 and rownum = 1;
ENAME SAL
----------
----------
MILLER
1300
이번엔 다음과 같은
질의를 보자
SQL>
select max(sal) - min(sal)
2
from emp
3
where deptno = 10;
MAX(SAL)-MIN(SAL)
-----------------
3700
데이터양이 대량인
경우 위질의보다 아래의 쿼리가 좋을 듯 하다.
with a as
(
select
sal
from
emp
where
deptno = 10
and sal > 0
and rownum = 1
) , b as
(
select
sal
from
emp
where
deptno = 10
and sal > 0
and rownum = 1
)
select
a.sal - b.sal from a, b
실제 많은 양의
데이터가 있는 경우 아래와 같은 결과가 나오니 참조 하시길…
SQL> set
autotrace on;
SQL>
select count(*) from emp3;
COUNT(*)
----------
7340032
SQL>
select max(sal) - min(sal)
2 from emp3
3 where deptno =
10;
MAX(SAL)-MIN(SAL)
-----------------
3700
경 과:
00:00:07.85
Execution
Plan
----------------------------------------------------------
0
SELECT STATEMENT Optimizer=ALL_ROWS (Cost=9707 Card=1
Bytes=
26)
1
0 SORT
(AGGREGATE)
2
1 TABLE ACCESS (FULL) OF
'EMP3' (TABLE) (Cost=9707 Card=16
67991
Bytes=43367766)
Statistics
----------------------------------------------------------
0
recursive calls
0
db block gets
43131
consistent gets
42199
physical reads
0
redo size
406
bytes sent via SQL*Net to client
512
bytes received via SQL*Net from client
2
SQL*Net roundtrips to/from client
0
sorts (memory)
0
sorts (disk)
1
rows processed
SQL>
with a as (
2 select
sal
3 from
emp
4 where deptno =
10
5 and sal > 0
6 and rownum = 1
7 ) , b as
(
8 select
sal
9 from
emp
10
where deptno = 10
11
and sal >
0
12
and rownum =
1
13
)
14
select a.sal - b.sal from a, b;
A.SAL-B.SAL
-----------
3700
경 과:
00:00:00.01
Execution
Plan
----------------------------------------------------------
0
SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=1
Bytes=26)
1
0 MERGE JOIN (CARTESIAN) (Cost=4
Card=1 Bytes=26)
2
1 VIEW (Cost=2 Card=1
Bytes=13)
3
2 COUNT
(STOPKEY)
4
3 TABLE ACCESS (BY INDEX
ROWID) OF 'EMP' (TABLE) (Cost
=2 Card=5
Bytes=35)
5
4 INDEX (RANGE SCAN
DESCENDING) OF 'IDX_EMP_SAL' (IN
DEX) (Cost=1
Card=14)
6
1 BUFFER (SORT) (Cost=4 Card=1
Bytes=13)
7
6 VIEW (Cost=2 Card=1
Bytes=13)
8
7 COUNT
(STOPKEY)
9
8 TABLE ACCESS (BY INDEX
ROWID) OF 'EMP' (TABLE) (Co
st=2 Card=5
Bytes=35)
10
9 INDEX (RANGE SCAN)
OF 'IDX_EMP_SAL' (INDEX) (Cos
t=1 Card=14)
Statistics
----------------------------------------------------------
0
recursive calls
0
db block gets
4
consistent gets
0
physical reads
0
redo size
400
bytes sent via SQL*Net to client
512
bytes received via SQL*Net from client
2
SQL*Net roundtrips to/from client
1
sorts (memory)
0
sorts (disk)
1
rows
processed
댓글 없음:
댓글 쓰기