[PLSQL,SQL교육강좌, 구로디지털단지오라클교육]SQL WHERE 와 HAVING
구로디지털 오엔제이프로그래밍실무교육센터
www.onjprogramming.co.kr
예문을 통해 WHERE를 쓰는 경우와 HAVING을 쓰는 경우의 차이에
대해 알아 보도록 하겠습니다.
n 실습을 위한
테이블을 만들자.
create table myemp1
(empno number not null primary key,
ename varchar2(100),
deptno number,
addr varchar2(100),
sal number
)
-- 실습을 위해 myemp1을 2000만건 만들자.
DECLARE
v_c
NUMBER := 1;
BEGIN
WHILE
(v_c <= 10000000) LOOP
insert into myemp1 values ( v_c,
'홍길동'||v_c, mod(v_c, 5), '서울'||v_c, mod(v_c, 1000000));
v_c := v_c +
1;
insert into myemp1 values ( v_c,
'다길동'||v_c, mod(v_c, 5), '부산'||v_c, mod(v_c, 1000000));
v_c
:= v_c + 1;
insert into myemp1 values ( v_c,
'나길동'||v_c, mod(v_c, 5), '대구'||v_c, mod(v_c, 1000000));
v_c
:= v_c + 1;
insert into myemp1 values ( v_c,
'나길동'||v_c, mod(v_c, 5), '광주'||v_c, mod(v_c, 1000000));
v_c
:= v_c + 1;
END
LOOP;
commit;
END;
create index idx_myemp1_deptno on myemp1(deptno)
SQL> set autotrace on explain
SQL> set timing on
아래 질의는 MYEMP1 테이블의 데이터를 DEPTNO 별로 그룹핑 하는데DEPTNO가 1번인 부서원들의 급여 합을 구하는 질의 입니다. (myemp1에는 dept인덱스가 걸려 있습니다)
약 10초 가까지 걸렸다.
SQL> select deptno, avg(sal)
2 from myemp1
3 group by deptno
4 having deptno = 1;
DEPTNO AVG(SAL)
---------- ----------
1 499998.5
경 과:
00:00:09.89
--------------------------------------
|
Id |
Operation |
Name |
--------------------------------------
| 0 | SELECT
STATEMENT | |
|* 1 | FILTER | |
| 2
| SORT GROUP
BY | |
| 3 | TABLE ACCESS FULL| MYEMP1
|
이 경우에는 Table을 FULL SCAN한 후 GROUP BY를 한 후 deptno가 1인 것을 찾기 위해 FILTER를 사용 했습니다.
이 번에는 having 대신 where절을 이용하여 같은 결과를 만들어 보도록
하겠습니다.
(현재 deptno 값은 0,1,2,3,4 5가지 값이 있어 분포도가 20%)
17초 정도 결렸다. 아마 데이터가 많아서 그런 모양이다. 테스트 해보라.
SQL> select
deptno, avg(sal)
2 from myemp1
3 where deptno =1
4 group by deptno;
DEPTNO AVG(SAL)
---------- ----------
1 499998.5
경 과: 00:00:17.29
Execution Plan
----------------------------------------------------------
| 0 | SELECT
STATEMENT | |
| 1 | SORT GROUP
BY | |
| 2
| TABLE ACCESS BY INDEX
ROWID| MYEMP1 |
|* 3
| INDEX RANGE
SCAN |
IDX_MYEMP1_DEPTNO |
----------------------------------------------------------
이 경우에는 DEPTNO의 인덱스를 이용하여 부분
검색을 통해 deptno가 10인 데이터를 꺼낸 후 GROUP BY를 시켜 count(*)를 구하였습니다.
이번에는 위 SQL문을 hash_sj(해시세미조인)을 시켜보자. 절반 정도 빨라진다.
SQL> select deptno, avg(sal)
2 from myemp1
3 where deptno =1
4 group by deptno;
DEPTNO AVG(SAL)
---------- ----------
1 499998.5
경 과: 00:00:08.43
Execution Plan
----------------------------------------------------------
| 0 | SELECT
STATEMENT | | 2339K| 58M| 16991 (1)|
| 1 | SORT GROUP BY
NOSORT| | 2339K| 58M| 16991 (1)|
|* 2
| TABLE ACCESS
FULL | MYEMP1
| 2339K| 58M|
16991 (1)|
아래처럼 집계된 값이 어떠하다라고
비교 할려면 반드시 having구만을 사용해야 합니다.
SQL> select
deptno, avg(sal)
2 from myemp1
3 group by deptno
4 having avg(sal) >
300000;
DEPTNO AVG(SAL)
---------- ----------
0 499997.5
1 499998.5
2 499999.5
3 500000.5
4 500001.5
경 과: 00:00:09.64
Execution Plan
-----------------------------------------------
Plan hash value: 2438610968
--------------------------------------
|
Id |
Operation |
Name |
--------------------------------------
| 0 | SELECT
STATEMENT | |
|* 1 | FILTER | |
| 2
| SORT GROUP
BY | |
| 3
| TABLE ACCESS FULL|
MYEMP1 |
--------------------------------------
댓글 없음:
댓글 쓰기