스타조인 중 카티젼 곱이 너무 크거나, 애써 준비한 상수집합이 팩트 집합의 처리범위를
제대로 줄여 주지 못한다면 너무 억울하다. 만약 카티젼 곱을 만들지 않아도, 수많은
결합인덱스를 가지고 있지 않아도 팩트 테이블의 처리범위를 쉽게 줄여 줄 수 있는 방법이
있다고 한다면 얼마나 좋겠는가 ? 스타변형(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
HASH JOIN <===== 액세스된 팩트 테이블 결과와 각 디멘전을 조인
TABLE ACCESS (FULL) OF 'DEPT'
TABLE ACCESS ( BY INDEX ROWID) OF 'SALES'
BITMAP CONVERSION ( TO ROWIDS ) <==== BITMAP 을 ROWID 로 CONVERSION 하여 팩트 테이블에 엑세스
BITMAP AND <==== BITMAP AND 수행
BITMAP MERGE
BITMAP KEY ITERATION
TABLE ACCESS (FULL) OF 'PRODUCTS'
<=== 각 서브쿼리를 먼저 수행하여 비트맵 생성{}
BITMAP INDEX (RANGE SCAN) OF 'SALES_PRODUCT_BX'
BITMAP MERGE
BITMAP KEY ITERATION
TABLE ACCESS (FULL) OF 'DEPT'
BITMAP INDEX (RANGE SCAN) OF 'SALES_DEPT_BX'
BITMAP MERGE
BITMAP KEY ITERATION
TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS'
INDEX ( RANGE SCAN) OF 'CUST_GRADE_IDX'
BITMAP CONVERSION ( FROM ROWIDS ) <=== 팩트 테이블에 비트맵 인덱스가 없으면 전환
INDEX ( RANGE SCAN) OF 'SALES_CUST_IDX'
TABLE ACCESS (FULL) OF 'PRODUCTS'
TABLE ACCESS ( BY INDEX ROWID ) OF 'CUSTOMERS'
INDEX (RANGE SCAN) OF 'CUST_STATE_PROVINCE_IDX'
스타변형조인이 일어나기 위해 사전에 반드시 준수되어야 할 필수적인 전제조건
1) 하나의 팩트 테이블과 최소한 2개 이상의 디멘전 테이블이 존재해야 한다.
2) 팩트 테이블에 있는 디멘젼\- 즉, 디멘전 테이블들의 외부키 - 에는 반드시 비트맵
인덱스가 존재해야 한다. 그러나, B-TREE 인덱스가 있어도 비트맵 컨버전이 일어나므로
스타변형 조인이 발생 할 수 있다. 그러나, 복합 비트맵 인덱스 상에서 발생할 때는
사용상의 주의가 필요하다.
3) 팩트 테이블에 반드시 통계정보가 생성(Analyze) 되어 있어야 한다. 그러나, ANANLYZE
모드(Mode)에는 영향을 받지 않는다.
4) Start_transformation_enabled 파라메터가 FALSE 가 아닌 TRUE 나 TEMP_DISABLE 로
설정되어 있거나, 아니면 쿼리에 직접 START_TRANSFORMATION 힌트를 주어야 작동한다.
스타변형조인의 제약조건
1) 비트맵을 사용할 수 없게 하는 힌트와는 서로 양립할 수 없다.
FULL, ROWID, START 와 같은 힌트는 논리적으로 이미 서로 공존할 수 없기 때문이다.
2) 쿼리 내에 바인드 변수(Bind variable)를 사용하지 않아야 한다.
어떤 경우의 바인드 상요도 스타변형 조인을 발생시키지 않는다.
스타변형 조인을 위한 WHERE 절의 바인드 변수 뿐만 아니라,
이와 상관없는 WHERE 절에 바인드 변수가 있어도 스타변형 조인이 일어나지 않는다.
3) 원격(REMOTE) 팩트 테이블인 경우에는 스타변형 조인이 일어나지 않는다.
4) 디멘전 테이블이 원격에 있으면 이 조인은 일어 날수 있다.
5) 부정형 조인으로 수행되는 경우에는 이 조인은 발생하지 않는다. [VLDB: 확인자 ]
6) 인라인뷰나 뷰 쿼리 중에는 독립적으로 먼저 수행될 수 있는 경우와 액세스 쿼리와
머지를 한 후에 수행될 수 있는 두 가지 종류가 있다. 후자의 경우는 이 조인이
일어날 수 없다.
7) 서브쿼리에 이미 디멘전 테이블로 사용한 테이블에 대해서는 이런 방식의 조인을
위한 변형(Transformation)이 일어나지 않는다. 여기서 말하는 서브쿼리는 변형에
의해 생성된 서브쿼리가 아니라 사용자가 쿼리에 직접 기술한 것을 말한다.