2013년 8월 13일 화요일

[오라클자바community강좌]EXISTS 와 DISTINCT 비교 설명 입니다. 참고하세요~

[오라클자바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" />DelhiSports
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
Delhi Sports
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
 
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', '나길동');
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);
commit
SQL> select * from cust;
CUST_ID        CUST_NAME                                         
-------------- --------------------------------------------------
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
4 rows selected.
 
-- 매출이 있는 고객데이터가 4건이다.
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.

댓글 없음:

댓글 쓰기