[오라클자바community강좌]EXISTS 와 DISTINCT 비교 설명 입니다. 참고하세요~
오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)
SELECT 문장에서 DISTINCT를 사용하는 이유는 중복된 행을 제거 하기 위해서 입니다. 이를 위해 오라클은 SORT를 수행 하며 소트를 위한 시간, 메모리 또는 디스크 공간이 필요 할 수도 있습니다. 그러니깐 가급적이면 사용 안 하는 것이 좋습니다. 추출되는 데이터가 순서에 의해 출력되지 않아도 된다면 아래의 경우처럼 EXISTS를 사용하는 것이 훨씬 효율적 입니다. 예제를 통해 이해 하도록 하겠습니다. 실제 비용은 1/10 정도로 줄게 됩니다.
:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
SQL> set autotrace on
SQL> select distinct c.name
2 from s_customer c, s_ord o
3 where c.id = o.customer_id;
NAME
--------------------------------------------------
Beisbol Si!
Big John's Sports Emporium
:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Delhi Sports
Futbol Sonora
Hamada Sport
Kam's Sporting Goods
Kuhn's Sports
Muench Sports
OJ Atheletics
Ojibway Retail
Sportique
NAME
--------------------------------------------------
Unisports
Womansport
13 개의 행이 선택되었습니다.
경 과: 00:00:00 .03
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (UNIQUE)
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'S_ORD'
4 2 TABLE ACCESS (BY INDEX ROWID) OF 'S_CUSTOMER'
5 4 INDEX (UNIQUE SCAN) OF 'S_CUSTOMER_ID_PK' (UNIQUE)
이 경우엔 S_ORD 테이블을 전체 스캔 한 데이터와 S_CUSTOMER 테이블의 데이터를 UNIQUE 인덱스를 이용하여 가져온 후 ROWIDD로 찾은 데이터와 비교하여 같은 아이디의 데이터가 있으면 추출하고 아니면 반복하는 구조를 가집니다. 그런 다음 c.name으로 SORT를 하게 되는 거죠…
Statistics
----------------------------------------------------------
80 recursive calls
0 db block gets
57 consistent gets
0 physical reads
0 redo size
651 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)
13 rows processed
이번엔 EXISTS를 이용하는 예 입니다.
SQL> select c.name
2 from s_customer c
3 where exists (select 1 from s_ord o
4 where o.customer_id = c.id);
NAME
--------------------------------------------------
Unisports
OJ Atheletics
Womansport
Kam's Sporting Goods
Sportique
Muench Sports
Beisbol Si!
Futbol Sonora
Kuhn's Sports
Hamada Sport
NAME
--------------------------------------------------
Big John's Sports Emporium
Ojibway Retail
13 개의 행이 선택되었습니다.
경 과: 00:00:00 .03
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'S_CUSTOMER'
3 1 TABLE ACCESS (FULL) OF 'S_ORD'
이 경우엔 S_CUSTOMER를 전체 스캔하고 S_ORD도 전체 스캔하여 필터링(ID가 같은 데이터가 있는지) 하므로 SORT를 이용하지는 않습니다. 그러므로 앞의 쿼리와 추출되는 데이터의 개수는 같지만 순서는 달리 나오는 겁니다.
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
49 consistent gets
0 physical reads
0 redo size
651 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
13 rows processed
[실습]
select * from dba_free_spaces
select * from dba_rollback_segs
select * from dba_rollback_segs
create table cust (
cust_id varchar2(10),
cust_name varchar2(50));
create table sale(
cust_id varchar2(10),
goods_id varchar2(10),
sale_amt number);
insert into cust values ('1', '김길동');
insert into cust values ('2', '홍길동');
insert into cust values ('3', '나길동');
cust_id varchar2(10),
cust_name varchar2(50));
create table sale(
cust_id varchar2(10),
goods_id varchar2(10),
sale_amt number);
insert into cust values ('1', '김길동');
insert into cust values ('2', '홍길동');
insert into cust values ('3', '나길동');
insert into sale values ('1', 'A001',1000);
insert into sale values ('1', 'B001',2000);
insert into sale values ('2', 'C001',4000);
insert into sale values ('2', 'D001',5000);
insert into sale values ('1', 'B001',2000);
insert into sale values ('2', 'C001',4000);
insert into sale values ('2', 'D001',5000);
commit
SQL> select * from cust;
CUST_ID CUST_NAME
-------------- --------------------------------------------------
1 김길동
2 홍길동
3 나길동
-------------- --------------------------------------------------
1 김길동
2 홍길동
3 나길동
3 rows selected.
SQL> select * from sale;
CUST_ID GOODS_ID SALE_AMT
-------------- ---------------- ----------------
1 A001 1000
1 B001 2000
2 C001 4000
2 D001 5000
-------------- ---------------- ----------------
1 A001 1000
1 B001 2000
2 C001 4000
2 D001 5000
4 rows selected.
-- 매출이 있는 고객데이터가 4건이다.
SQL> select c.cust_name
from cust c, sale s
where c.cust_id = s.cust_id;
SQL> select c.cust_name
from cust c, sale s
where c.cust_id = s.cust_id;
CUST_NAME
--------------------------------------------------
김길동
김길동
홍길동
홍길동
--------------------------------------------------
김길동
김길동
홍길동
홍길동
4 rows selected.
-- 이름이 같으면 한건만 로딩
SQL> select distinct c.cust_name
from cust c, sale s
where c.cust_id = s.cust_id;
CUST_NAME
--------------------------------------------------
김길동
홍길동
--------------------------------------------------
김길동
홍길동
2 rows selected.
-- exists로 구현
SQL> select c.cust_name
from cust c
where exists (select 1 from sale s
where s.cust_id = c.cust_id);
CUST_NAME
--------------------------------------------------
김길동
홍길동
--------------------------------------------------
김길동
홍길동
2 rows selected.
댓글 없음:
댓글 쓰기