2013년 9월 2일 월요일

[오라클강좌]SQL Max값을 효율적으로 구하기 , 오라클SQL MAX

SQL Max값을 효율적으로 구하기

 다음과 같이 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
 


댓글 없음:

댓글 쓰기