다음과 같이 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
댓글 없음:
댓글 쓰기