메뉴 건너뛰기

bysql.net

이화식 선생님의 새로쓴 대용량 데이터 베이스 1의 온라인 스터디 입니다.
매주 각 스터디 팀원들이 담당 분량을 정리해서 올리고 토론식으로 진행합니다.
스터디 포스팅은 팀원들에의해 이루어지지만 스터디 참여는 사이트 회원 모두가 가능합니다.

진행기간: 2009.07 ~ 2009.10. 종료

2부-1.4-부분범위처리로의유도.hwp

 

1.4 부분범위처리로의 유도

- 이장에서는 어떤 SQL 문들을 부분범위 처리로 유도할 수 있는 지 각 방법들을 살펴본다.


1.4.1. 액세스 경로를 이용한 SORT의 대체

-  ORDER BY에 의한 전체처리 범위

- 예 1 : 인덱스를 이용하여 정렬된 순서대로 추출하는 부분범위 처리 방법

  (SQL 문) - 전체처리

 SELECT *

 FROM product

 WHERE item_cd LIKE 'AB%' AND category LIKE 'C%'

 ORDER BY item_cd DESC

  (SQL 문) - item_index를 이용하여 부분범위처리.

 SELECT /*+ INDEX_DESC(product item_index)*/ *

 FROM product

 WHERE item_cd LIKE 'AB%' AND category LIKE 'C%'

- 예 2 :

  (SQL 문) - 전체처리 - ORDER BY 컬럼과 인덱스가 다를때

 SELECT *

 FROM order

 WHERE ord_date like '2005%'

 ORDER BY ord_dept DESC

  (SQL 문) - 부분범위처리 - ord_dept를 액세스할 때 자동으로 정렬됨.

 SELECT /*+ INDEX_DESC(a ord_dept_index)*/ *

 FROM order a

 WHERE ord_date like '2005%' AND ord_dept > ' ';


1.4.2. 인덱스만 액세스하는 부분범위 처리

-  인덱스만 사용하는 실행계획 수립 조건

 질의에 사용된 모든 컬럼이 하나의 인덱스에 결합되어 있거나

 인덱스 머지되는 실행계획의 경우 머지되는 두 개의 인덱스에 모든 컬럼이 사용되어야 한다.

 질의에 사용된 전체 컬럼이 몇 개의 인덱스에 포함되면 인덱스 조인 성립

- 예 1 : ord_date 인덱스보다는 (ord_date+qty) 인덱스가 2배 이상 빠르다.

  (SQL)

 SELECT ord_date, SUM(qty)

 FROM order

 WHERE ord_date like '200510%'

 GROUP BY ord_date

- 예 2 : 적절한 인덱스 구성

  (SQL) (ord_date+agent_cd)를 사용한다면 약간 비효율적이다.

 SELECT ord_date, count(*)

 FROM order

 WHERE ord_date like '200510%'

 GROUP BY ord_dept

  (SQL) (ord_date+agent_cd)를 사용한다면 매우 효율적이다.

 SELECT ord_date, count(*)

 FROM order

 WHERE ord_date like '200510%'

 GROUP BY agent_cd


1.4.3. MIN, MAX의 처리

- sequence를 사용하는 방법(생략)


1.4.4. FILTER 형 부분범위 처리

- 예 1 : 필터형 처리를 유도하는 것이 좋은 사례

  (SQL) 전체범위 처리 예(COUNT()함수의 목적이 결과의 존재를 확인)

 SELECT count(*) INTO :cnt

 FROM ITEM_TAB

 WHERE DEPT='101' AND seq > 100

   ...

 IF cnt > 0 ... 

  (SQL) 부분범위 처리 예(EXIST로 변환한 예)

 SELECT INTO :cnt FROM DUAL

 WHERE EXISTS (SELECT 'X' FROM ITEM_TAB

              WHERE DEPT='101' AND seq > 100)

   ...

 IF cnt > 0 ... 

  (실행계획)

 SELECT STATEMENT

   FILTER

     TABLE ACCESS (FULL) OF 'DUAL'

     TABLE ACCESS (BY INDEX ROWID) OF 'ITEM_TAB'

       INDEX (RANGE SCAN) OF item_dept_idx(NON-UNIQUE)


- 예 2 : 필터형 처리를 유도하는 것이 좋은 사례

  (SQL) 전체범위 처리 예(MINUS)

 SELECT ord_dept, ord_date, custno

 FROM order

 WHERE ord_date like '2005%'

 MINUS

 SELECT ord_dept, ord_date, '12541'

 FROM sales

 WHERE cust_no='12541'

  (SQL) 부분범위 처리 예(EXIST로 변환한 예)

 SELECT ord_dept, ord_date, custno

 FROM order x

 WHERE ord_date like '2005%' AND

  NOT EXISTS ( SELECT * FROM sales y

    WHERE y.ord_dept=x.ord-dept AND

     t.ord_date=x.ord_date AND cust_no='12541')


1.4.5. ROWNUM의 활용

- ROWNUM - 가상의 컬럼으로 SQL 결과 튜플의 일련 번호이다.

- 예 : 10개의 결과 튜플이 생성되면 실행중지, 아니면 전체를 모두 수행.

 SELECT *

 FROM ITEM_TAB

 WHERE DEPT='101' AND seq > 100 AND ROWNUM <= 10

- 실행계획의 예

 SELECT STATEMENT

   COUNT(STOPKEY)

     TABLE ACCESS (FULL) OF table

- ROWNUM 사례 - ROWNUM 순서와 item_cd 정렬순과 일치(내부저장을 하지 않으므로)

   SELECT ROWNUM, item_cd, category_cd

 FROM product

 WHERE deptno like '120%' and qty >0 and ROWNUM <=10

 ORDER BY item_cd

- ROWNUM 사례 - ROWNUM 순서와 item_cd 정렬순과 일치(전체범위처리)

   SELECT ROWNUM, item_cd, category_cd

 FROM ( SELECT *  FROM product

  WHERE deptno like '120%' and qty >0 ORDER BY item_cd)

  WHERE ROWNUM <=10

- ROWNUM 사례 - GROUP BY 결과를 원하는 수 만큼 출력하고 싶을 때

 SELECT ROWNUM, dept, totqty

 FROM ( SELECT deptno, sum(qty) totqty FROM product

  WHERE deptno like '120%' GROUP BY deptno)

  WHERE ROWNUM <=10

- ROWNUM 사례 - GROUP BY 결과중 5번째 결과만 출력하고 싶을 때

 SELECT ROWNUM, dept, totqty

 FROM ( SELECT ROWNUM as RNUM, deptno, totqty

  FROM ( SELECT deptno, sum(qty) totqty FROM product

   WHERE deptno like '120%' AND ROWNUM <= 100

   GROUP BY deptno)

     )

  WHERE RNUM=5 AND ROWNUM =1  /* 불필요한 처리 없애기 */

- ROWNUM 사례 - 사용자의 무제한 액세스를 방지하고 싶을 때

 SELECT *

 FROM table

  WHERE conditions AND ROWNUM <= 1000

 

1.4.6. 인라인뷰를 이용한 부분범위 처리

- 인라인뷰를 활용하여 부분범위처리를 유도하는 원리는 전체범위처리가 되는 부분을 인라인뷰로 묶어서 다른 부분들은 부분범위처리가 되도록 한다.

- 예 1 : 세 개의 테이블을 조인 - 처리대상이 적은 테이블을 먼저 처리하여 전체범위가 되도록하고 대량의 테이블은 부분범위처리로 유도

   (SQL 1) 세 테이블 조인

 SELECT a.dept_name, b.empno, b.emp_name, c.sal_ym, c.sal_tot

 FROM department a, employee b, salary c

 WHERE b.deptno=a.deptno AND c.empno=b.empno AND

  a.location='SEOUL AND b.job='MANAGER' AND c.sal_ym='200512'

 ORDER BY a.dept_name, b.hire_date, c.sal_ym

   (SQL 2) 세 개의 테이블을 조인 - salary 테이블이 대용량인 경우 인라인뷰를 이용하여 dept, employee 조인한 후 (empno+sal_ym) 인덱스 사용하여 salary와 조인

 SELECT /*+ ORDERED, USE_NL(x,y) */

  a.dept_name, b.empno, b.emp_name, c.sal_ym, c.sal_tot

 FROM (SELECT a.dept_name, b.hire_date, b.empno, b.emp_name

  FROM dept a, employee b

  WHERE b.deptno=a.deptno AND a.location='SEOUL

   AND b.job='MANAGER'

  ORDER BY a.dept_name, b.hire_date) x, salary y

 WHERE y.empno=x.empno AND c.sal_ym='200512'

- 예 2 : GROUP BY를 통하여 가동된 중간집합을 생성하고 나머지는 참조되는 일종의 디멘전 테이블들을 부분범위처리로 유도하는 경우

   (SQL 1)

 SELECT a.product_cd, product_name, avg_stock

 FROM product a,

  (SELECT product_cd, SUM(stock_qty) / (:b2-:b1) avg_stock

  FROM prod_stock

  WHERE stock_date BETWEEN :b1 AND :b2

  GROUP BY product_cd) b

 WHERE b.product_cd=a.product_cd AND a.category_cd='20';


   (최적이 수행절차)

 product의 category_cd 값이 20인 product_cd 속성을 찾는다.

 구해진 product_cd 값과 stock_date 값으로 prod_stock 테이블을

  (product_cd+stock_date) 인덱스를 이용하여 액세스한다.

 위 작업을 반복하다 운반단위가 채워지면 종료한다.

   (해결방법) 사용자지정 저장함수 사용 혹은 스칼라 서브쿼리 사용

   (SQL 2) 스칼라 서브쿼리 사용 예

 SELECT a.product_cd, product_name,

  (SELECT SUM(stock_qty) / (:b2-:b1) avg_stock

  FROM prod_stock b

  WHERE b.product_cd=a.product_cd AND

   stock_date BETWEEN :b1 AND :b2) avg_stock

 FROM product a,

 WHERE category_cd='20';


1.4.7저장형 함수를 이용한 부분범위 처리

- (생략)

번호 제목 글쓴이 날짜 조회 수
25 2.3.4. 해쉬 (Hash) 조인 file 휘휘 2009.09.14 98316
24 2.3. 조인 종류별 특징및 활용 방안 휘휘 2009.09.13 93141
23 2부 2.3.(2.3.6-2.3.8) 조인 종류별 특징 및 활용 방안(스타조인, 비트맵조인인덱스) [1] file balto 2009.09.08 107164
22 제2부 2장 조인의 최적화 방안 file 휘휘 2009.09.06 98430
21 제2부 1.4.7. 저장형 함수를 이용한 부분 범위 처리 휘휘 2009.09.06 81256
20 2.2. 연결고리 상태가 조인에 미치는 영향 file balto 2009.09.05 118356
» 2부 1.4.(1.4.1-1.4.7) 부분범위처리로의 유도 (중요하지 않은 부분 조금 미완성) file balto 2009.08.29 95782
18 4.2. 클러스터링 형태의 결정 기준 file balto 2009.08.27 99654
17 4.1.6. 인덱스 선정 절차 휘휘 2009.08.24 102475
16 3.2.4. 비트맵(Bitmap) 실행계획 휘휘 2009.08.24 95079
15 3.3. 실행계획의 제어 [1] 휘휘 2009.08.18 100496
14 4.1. 인덱스 선정기준(4.1.1.-4.1.5.) [3] file balto 2009.08.17 100770
13 3.2.2. 데이터 연결을 위한 실행 계획 [2] file balto 2009.08.06 101229
12 3.2. 실행계획의 유형 (1/3) - 3.2.1. 스캔의 기본유형 휘휘 2009.08.03 103259
11 3.1 SQL의 실행계획 (2/3) 운영자 2009.07.25 101063
10 3.1 SQL의 실행계획 (3/3) file 운영자 2009.07.19 93361
9 3.1 SQL의 실행계획 (1/3) 운영자 2009.07.19 102161
8 2.2. 비트맵(Bitmap) 인덱스 [2] file 휘휘 2009.07.15 122543
7 2.3 함수기반 인덱스 (FBI,Function-Based Index) [1] 운영자 2009.07.12 160348
6 2.1. B-tree 인덱스 [2] 운영자 2009.07.10 107210