WHERE versus HAVING
오라클자바커뮤니티에서 설립한 오엔제이프로그래밍
실무교육센터
(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)
예문을 통해 WHERE를 쓰는 경우와 HAVING을 쓰는 경우의 차이에 대해 알아 보도록 하겠습니다. 어느 방법이 효율이 좋을지 미리 추측을 해보시죠^^;;;
저의 경우 통계 정보를 보기 위해 set autotrace 를 사용했으며 이 부분에 대한 내용은 Oracle 튜닝 강좌를 참고하시기 바랍니다.
참고로 아래 myemp 테이블은 10만건 정도의 레코드를 가지고 있으며 deptno는 외래키로서 인덱스가 걸려 있습니다.
SQL> set autotrace on
SQL> set timing on
아래 질의는 MTEMP 테이블의 데이터를 DEPTNO 별로 그룹핑 하는데 DEPTNO가 10번인 부서원들의 수를 COUNT하는 질의 입니다.
SQL> select deptno, count(*)
2 from myemp
3 group by deptno
4 having deptno = 10;
선택된 레코드가 없습니다.
경 과: 00:00:00.05
Execution Plan
-----------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 FILTER
2 1 SORT (GROUP BY)
3 2 TABLE ACCESS (FULL) OF 'MYEMP'
이 경우에는 Table을 FULL SCAN한 후 GROUP BY를 한 후 deptno가 10인 것을 찾기 위해 FILTER를 사용 했습니다. 통계정보는 아래와 같습니다.
Statistics
-----------------------------------------------------
0 recursive calls
0 db block gets
304 consistent gets
275 physical reads
0 redo size
282 bytes sent via SQL*Net to client
372 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed
이 번에는 having 대신 where절을 이용하여 같은 결과를 만들어 보도록 하겠습니다.
SQL> select deptno, count(*)
2 from myemp
3 where deptno = 10
4 group by deptno;
선택된 레코드가 없습니다.
경 과: 00:00:00.04
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 INDEX (RANGE SCAN) OF 'IDX_MYEMP_DEPTNO' (NON-UNIQUE)
이 경우에는 DEPTNO의 인덱스를 이용하여 부분 검색을 통해 deptno가 10인 데이터를 꺼낸 후 GROUP BY를 시켜 count(*)를 구하였습니다.
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
59 consistent gets
30 physical reads
1748 redo size
282 bytes sent via SQL*Net to client
372 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed
두 번째의 경우(where를 이용하는 경우)가 deptno에 인덱스가 걸려 있는 경우 약간 효율이 앞선 다고 할 수 있습니다. 시간도 쬐금 앞서구요… 하지만 무조건은 절대 아닙니다. 때에 따라서는 데이터를 먼저 집계를 낸 후 집계된 데이터를 조건을 주어 비교하는 경우도 있으니까요.. 특히 집계된 값이 어떠하다라고 비교 할려면 having구만을 사용해야 합니다. 아래처럼 말입니다.
SQL> select deptno, count(*)
2 from myemp
3 group by deptno
4 having sum(sal) > 2000;
DEPTNO COUNT(*)
---------- ----------
30 49002
40 16533
2 개의 행이 선택되었습니다.
경 과: 00:00:00.07
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 FILTER
2 1 SORT (GROUP BY)
3 2 TABLE ACCESS (FULL) OF 'MYEMP'
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
304 consistent gets
300 physical reads
0 redo size
482 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
2 rows processed
댓글 없음:
댓글 쓰기