====3.3.7. 퀴리형태 변형(Query Transformation)을 위한 힌트==== *앞서서 옵티마이져의 최적화 단계에서 살펴본 "질의 변환기"가 수행하는 퀴리의 변형과 같은 질의 변환을 HINT를 사용해 옵티마이저에게 권고할 수 있다. ===USE_CONCAT=== *조건절에 있는 OR 연산자 조건(또는 IN 연산자 조건)을 별도의 실행단위로 분리하여 각각의 최적의 액세스 경로를 수립하여 이를 연결(Concatenation)하는 실행계획을 수립하도록 유도하는 힌트이다. *반드시 처리주관 조건이 OR로 나누어졌을 때 적용해야 하며, 잘못 사용하면 비효율이 발생할 수 잇으므로 주의해야 한다. 예) SELECT /*+ USE_CONCAT */.... FROM emp WHERE job = 'CLERK' OR deptno = 10; ===NO_EXPAND=== *조건절에 있는 OR연산자 조건(또는 IN 연산자 조건)을 별도 실행단위로 분리하여 처리하지 않도록 할 때 사용하는 힌트이다. *USE_CONCAT의 반대 개념이다. 예) SELECT /*+ NO_EXAPND */.... FROM CUSTOMER WHERE CUST_TYPE IN ('A', 'B'); ===REWRITE=== *대량의 데이터를 대상으로 하는 조인이나 그룹함수 사용하여 가공집합을 얻고자할 때 수행속도 향상을 위해 미리 생성된 실체뷰(Materialized View)를 생성할수 있다. *우리가 어떤 쿼리를 수행하였을 때 옵티마이져는 원래의 테이블을 액세스하는 방법과 실체뷰를 액세스하는 방법 중에서 유리한 것을 선택하도록 쿼리를 변형할수 있다. 이것을 '쿼리 재작성(Query rewrite)'이라고 하는데 이 힌트는 이러한 과정을 실행하도록 하는 힌트이다. *만약, 힌트내에 특정 실체뷰가 지정되어 있으면 비용에 상관없이 해당 실체뷰를 사용하게 된다. 이 때 힌트 내에 포함되지 않는 실체뷰는 고려대상이 아니다. *만약 힌트내에 실체뷰를 지정하지 않으면 적용 가능한 실체뷰를 찾아서 비용에 상관없이 그 실체뷰를 사용한다. 예) SELECT /*+ REWRITE (sales_mv) */ c.cust_id, MIN(c.cust_name), COUNT(distinct order_id) FROM sales s, order o, customer c WHERE s.order_id = o.order_id AND o.order_cust = c.cust_id GROUP BY c.cust_id; ===NO_REWRITE=== *QUERY_REWRITE_ENABLED 파라메터가 TRUE로 정의되어 있더라도 이를 무시하고 쿼리 블록에 대한 쿼리 재생성를 하지 않도록 유도한다. 예) SELECT /*+ NOREWRITE */ sum(s.amount_sold) AS dollars FROM sales s, times t WHERE s.time_id = t.time_id GROUP BY t.calendar_month_desc; \\ *실체뷰를 통해 쿼리 수행결과를 미리 저장하고 있는 경우에는 원래의 테이블로부터 직접 재계산을 유도함으로써 최신의 값으로 결과를 출력하도록 할 때 유용하게 사용된다. 버전에 따라 NO_REWRITE로 사용되기도 한다. ===MERGE=== *뷰나 인라인뷰의 액세스를 최적화기 위해서는 뷰쿼리에 사용된 원래의 테이블을 최적으로 액세스하도록 문장을 변환시켜야 한다. 이 과정을 뷰병합이라고 하며, 주어진 상황에 따라 다양한 현상이 나타난다. *이 힌트는 뷰병합이 가능함에도 불구하고 뷰병합이 일어나지 않을 때 적용할수 있다. *주로 복잡한 뷰나 인라인 뷰일 때 가끔 적용해 보면 상당한 효과를 얻는 경우가 많이 있다. 예) SELECT /*+ MERGE(table_name) */....... ===NO_MERGE=== *뷰쿼리 병합이 일어나지 않도록 요구하는 힌트이다. *주어진 조건이나 처리형태에 따라 **뷰 병합을 하지 않고 먼저 뷰를 수행한 결과를 이용해 다음 처리를 하는 것이 유리**한 경우도 많이 있다. 이러한 경우에 뷰 병합을 방지하기위해 사용하는 힌트 이다. 예) SELECT /*+ NO_MERGE(table_name) */........... ===STAR_TRANSFORMATION=== *스카 변형 조인(Star transformation join)을 수행하도록 요구하는 힌트이다. 이조인은 **소량의 데이터를 가진여러 개의 디멘전 테이블과 팩트 테이블의 개별 비트맵 인덱스를 이용하여 처리범위를 줄이는 조인방식**이다. 이 조인은 내부적으로 옵티마이져가 질의를 변형하여 실행계획을 생성하게 한다. *참고: 이 조인에 대한 상세내용은 [ 제2부 조인의 최적화' 단원에 있는 '스타변형 조인(page 617~630) ] 예) SELECT /*+ STAR_TRANSFORMATION */ 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.dept_name, c.cust_city, p.product_name); \\ *NO_STAR_TRANSFORMATION 힌트는 옵티마이져로 하여금 스타변형 조인을 하지 않도록 유도한다. ===FACT=== *스타변형 조인에서 팩트 테이블을 지정하기 위해서는 사용하는 힌트이다. 대부분의경우는 옵티마이져에게 맡기는 것이 바람직하지만 팩트 테이블 선정에 오류가 있어서 원하지 않는 실행계획이 나타났을때 사용할수 있다. *NO_FACT힌트는 지정한 테이블을 팩트 테이블로 인정하지 말아달라는 요구를 하는 힌트이다. NO_FACT 힌트는STAR_TRANSFORMATION 상황에서 옵티마이져가 지정한 테이블을 FACT테이블로 고려하지 않도록 유도한다. ===UNNEST=== *서브쿼리와 메인쿼리를 합쳐 조인 형태로 변형하도록 하는 실행계획을 생성하도록 유도하는 힌트이다. 예) SELECT /*+ UNNEST(@qb) */............ FROM emp e WHERE e.deptno IN (SELECT /*+ QB_NAME(qb) */ d.deptno FROM dept d WHERE d.loc = 'DALLAS'); \\ *NO_UNNEST힌트는 UNNESTING을 하지 않도록 유도한다. ==참조한문서== "오라클클럽" http://wiki.oracleclub.com/pages/viewpage.action?pageId=1966265&