새로쓴 대용량 데이터베이스솔루션 1 (2008년)
스타변형(Star Transformation) 조인 0 0 5,143

by 구루비 스타변형 조인 [2009.05.17]


2.3.7. 스타변형(Star Transformation) 조인

 스타조인 중 카티젼 곱이 너무 크거나, 애써 준비한 상수집합이 팩트 집합의 처리범위를
제대로 줄여 주지 못한다면 너무 억울하다. 만약 카티젼 곱을 만들지 않아도, 수많은
결합인덱스를 가지고 있지 않아도 팩트 테이블의 처리범위를 쉽게 줄여 줄 수 있는 방법이
있다고 한다면 얼마나 좋겠는가 ? 스타변형(Star Transformation) 조인에 대해서
상세하게 알아보기로 하자.

 스타변형 조인은 비트맵 인덱스의 특성을 살린 것이다. 따라서 비트맵 인덱스이 장*단점을
그대로 승계하고 있다. 스타조인은 카티젼 곱을 만들었지만 스타변형조인은 비트맵
인덱스를 활용한다. 비트맵 인덱스는 그 구조적인 특성으로 인해 각각의 독립된
인덱스르 머지하더라도 그다지 부담이 되지 않는다.

SELECT *
FROM  sales
WHERE product_cd like 'PA%'
AND   sales_dept between '2110' and '2310'
\-\- product_cd 와 sales_dept 로 각각 비트맵 인덱스가 생성되어 있다고 가정

SELECT STATEMENT Optimizer=ALL_ROWS
  TABLE ACCESS ( BY INDEX ROWID ) OF 'SALES'
   BITMAP CONVERSION ( TO ROWIDS )
    BITMAP AND
      BITMAP MERGE
       BITMAP INDEX ( RANGE SCAN) OF 'SALES_PRODUCT_BX'
      BITMAP MERGE
       BITMAP INDEX ( RANGE SCAN) OF 'SALES_DEPT_BX'      
==> 비트맵 인덱스는 그들이 결합 인덱스로 구성되어 있지 않더라도 각각을
       서로 결합(BITMAP AND)하여 테이블을 액세스한다.      

SELECT d.dept_name, c.cust_city, p.product_name,
       SUM(s.amount) sales_amount
FROM  SALES s, PRODUCTS t, CUSTOMERS c, DEPT d
WHERE s.product_cd = t.product_cd
  AND s.cust_id = c.cust_id
  AND s.sales_dept = d.dept_no
  AND c.cust_grade between '10 and '15'
  AND d.location = 'SEOUL'
  AND p.product_name IN ('PA001','DR210')
GROUP BY d.dpet_name, c.cust_city, p.product_name ;
 
이와 같은 SQL  을 수행하여 스타변형조인으로 실행되면 아래와 같은 SQL 이
내부적으로 변형(Transformation) 되어 수행된다.

SELECT d.dept_name, c.cust_city, p.product_name,
       SUM(s.amount) sales_amount
FROM  SALES s, PRODUCTS t, CUSTOMERS c, DEPT d
WHERE s.product_cd = t.product_cd
  AND s.cust_id = c.cust_id
  AND s.sales_dept = d.dept_no
  AND c.cust_grade between '10 and '15'
  AND d.location = 'SEOUL'
  AND p.product_name IN ('PA001','DR210')
  AND s.product_cd IN ( SELECT product_cd FROM PRODUCTS
                        WHERE product_name IN ('PA001','DR210'))
  AND s.cust_id IN ( SELECT cust_id FROM CUSTOMERS
                        WHERE cust_grade between '10' and '15')
  AND s.sales_dpet IN ( SELECT dept_cd FROM DEPT
                        WHERE location = 'SEOUL')
GROUP BY d.dpet_name, c.cust_city, p.product_name ;            
   
스타변형조인이라고 부르는 이유는 바로 이처럼 내부적으로 SQL 을 변형시켜 수행되기
문이다. 이렇게 수행된 SQL 의 실행계획을 확인해보자

SELECT STATEMENT Optimizer=ALL_ROWS
  SORT GROUP BY
    HASH JOIN
      HASH JOIN
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HASH JOIN&nbsp; <===== 액세스된 팩트 테이블 결과와 각 디멘전을 조인
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TABLE ACCESS (FULL) OF 'DEPT'
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TABLE ACCESS ( BY INDEX ROWID) OF 'SALES'
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP CONVERSION ( TO ROWIDS )&nbsp; <==== BITMAP 을 ROWID 로 CONVERSION 하여 팩트 테이블에 엑세스
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP AND&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <==== BITMAP AND 수행

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP MERGE

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP KEY ITERATION

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TABLE ACCESS (FULL) OF 'PRODUCTS'&nbsp;&nbsp;

<=== 각 서브쿼리를 먼저 수행하여 비트맵 생성{}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP INDEX (RANGE SCAN) OF 'SALES_PRODUCT_BX'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP MERGE

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP KEY ITERATION

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TABLE ACCESS (FULL) OF 'DEPT'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP INDEX (RANGE SCAN) OF 'SALES_DEPT_BX'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP MERGE

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP KEY ITERATION

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX ( RANGE SCAN) OF 'CUST_GRADE_IDX'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BITMAP CONVERSION ( FROM ROWIDS ) <=== 팩트 테이블에 비트맵 인덱스가 없으면 전환

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INDEX ( RANGE SCAN) OF 'SALES_CUST_IDX'

&nbsp;&nbsp;&nbsp;&nbsp; TABLE ACCESS (FULL) OF 'PRODUCTS'
&nbsp;&nbsp; TABLE ACCESS ( BY INDEX ROWID ) OF 'CUSTOMERS'
&nbsp;&nbsp;&nbsp; INDEX (RANGE SCAN) OF 'CUST_STATE_PROVINCE_IDX'
&nbsp;&nbsp;&nbsp;
스타변형조인이 일어나기 위해 사전에 반드시 준수되어야 할 필수적인 전제조건

1) 하나의 팩트 테이블과 최소한 2개 이상의 디멘전 테이블이 존재해야 한다.
2) 팩트 테이블에 있는 디멘젼\- 즉, 디멘전 테이블들의 외부키 - 에는 반드시 비트맵
&nbsp;&nbsp; 인덱스가 존재해야 한다. 그러나, B-TREE 인덱스가 있어도 비트맵 컨버전이 일어나므로
&nbsp;&nbsp; 스타변형 조인이 발생 할 수 있다. 그러나, 복합 비트맵 인덱스 상에서 발생할 때는
&nbsp;&nbsp; 사용상의 주의가 필요하다.
3) 팩트 테이블에 반드시 통계정보가 생성(Analyze) 되어 있어야 한다. 그러나, ANANLYZE&nbsp;
&nbsp;&nbsp; 모드(Mode)에는 영향을 받지 않는다.&nbsp;&nbsp;
4) Start_transformation_enabled 파라메터가 FALSE 가 아닌 TRUE 나 TEMP_DISABLE 로
&nbsp;&nbsp; 설정되어 있거나, 아니면 쿼리에 직접 START_TRANSFORMATION 힌트를 주어야 작동한다.
&nbsp;&nbsp;
스타변형조인의 제약조건
1) 비트맵을 사용할 수 없게 하는 힌트와는 서로 양립할 수 없다.
&nbsp;&nbsp; FULL, ROWID, START 와 같은 힌트는 논리적으로 이미 서로 공존할 수 없기 때문이다.
2) 쿼리 내에 바인드 변수(Bind variable)를 사용하지 않아야 한다.
&nbsp;&nbsp; 어떤 경우의 바인드 상요도 스타변형 조인을 발생시키지 않는다.
&nbsp;&nbsp; 스타변형 조인을 위한 WHERE 절의 바인드 변수 뿐만 아니라,
&nbsp;&nbsp; 이와 상관없는 WHERE 절에 바인드 변수가 있어도 스타변형 조인이 일어나지 않는다.
3) 원격(REMOTE) 팩트 테이블인 경우에는 스타변형 조인이 일어나지 않는다.
4) 디멘전 테이블이 원격에 있으면 이 조인은 일어 날수 있다.
5) 부정형 조인으로 수행되는 경우에는 이 조인은 발생하지 않는다. [VLDB: 확인자 ]
6) 인라인뷰나 뷰 쿼리 중에는 독립적으로 먼저 수행될 수 있는 경우와 액세스 쿼리와
&nbsp;&nbsp; 머지를 한 후에 수행될 수 있는 두 가지 종류가 있다. 후자의 경우는 이 조인이
&nbsp;&nbsp; 일어날 수 없다.
7) 서브쿼리에 이미 디멘전 테이블로 사용한 테이블에 대해서는 이런 방식의 조인을
&nbsp;&nbsp; 위한 변형(Transformation)이 일어나지 않는다. 여기서 말하는 서브쿼리는 변형에
&nbsp;&nbsp; 의해 생성된 서브쿼리가 아니라 사용자가 쿼리에 직접 기술한 것을 말한다.

문서에 대하여

  • 이 문서는 오라클클럽 대용량 데이터베이스 스터디 모임에서 작성하였습니다.
  • {*}이 문서의 내용은 이화식님의 새로쓴 대용량 데이터베이스 솔루션을 참고했습니다.*
  • 이 문서를 다른 블로그나 홈페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^\^
"구루비 데이터베이스 스터디모임" 에서 2008년에 "새로쓴 대용량 데이터베이스 솔루션1" 도서를 스터디하면서 정리한 내용 입니다.

- 강좌 URL : http://www.gurubee.net/lecture/2596

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입