행위

튜닝 쿼리 변형

DB CAFE

Dbcafe (토론 | 기여)님의 2023년 6월 12일 (월) 22:03 판 (서브쿼리 Unnesting)
thumb_up 추천메뉴 바로가기


1 쿼리 변환 종류[편집]

  1. 10g부터는 서브쿼리 Unnesting과 뷰 Merging이 비용기반 쿼리 변환으로 전환됨
  2. 조건절 Pushing 중 조인 조건 pushdown도 비용기반 쿼리 변화으로 전환
  3. 나머지는 변환된 쿼리가 항상 더 나은 성능을 제공하므로 비용기반으로 전환이 불필요

1.1 서브쿼리 Unnesting[편집]

/*+ UNNEST */ /*+ NO_UNNEST */

Setting the UNNEST_SUBQUERY session parameter to TRUE enables subquery unnesting. Subquery unnesting unnests and merges the body of the subquery into the body of the statement that contains it, allowing the optimizer to consider them together when evaluating access paths and joins.
  • UNNEST_SUBQUERY 세션 매개변수를 TRUE로 설정하면 하위 쿼리 중첩 해제가 활성화됩니다.
  • 서브 쿼리의 중첩을 해제하여 메인쿼리에 병합토록 지시하여 옵티마이저가 액세스 경로 및 조인을 평가할 때 이들을 함께 고려할 수 있도록 합니다.
  1. 옵티마이져가 동일한 결과를 보장하는 조인문으로 변환하고 나서 최적화 하는것 이를 '서브쿼리 Unnesting' 이라고 함.
  2. 서브쿼리를 메인쿼리로 내몰아서(unnesting) 내서 메인쿼리와 조인 하도록 유도하는 하는 힌트, 즉 중첩(NEST)을 풀어서(UNNEST) 해제 하는 힌트 임.
    1. UNNEST는 뷰/서브쿼리를 해체한다. NO_UNNEST는 반대로 뷰/서브쿼리를 해체하지 말아라.
    2. FILTER 동작방식을 선택하지 않고 조인 동작방식으로 처리하고자 할 때. 서브쿼리에 UNNEST 힌트 사용
  3. 서브쿼리(Sub Query)는 메인 쿼리문의 WHERE 절에 나타날 때 중첩 됨.
    1. Oracle Database가 중첩된 서브 쿼리가있는 문을 측정(평가)할 때 서브 쿼리 부분을 여러 번 평가해야하며 일부 효율적인 액세스 경로 또는 조인을 간과 할 수 있습니다.
  4. 서브쿼리 중첩해제(SubQuery UNNEST)는 서브쿼리의 본문을 포함하는 명령문의 본문에 중첩해제(Unnest) 와 병합(Merge) 하여 옵티마이저가 액세스 경로 및 조인을 평가할 때 함께 고려할 수 있도록합니다.
  5. 변환된 쿼리의 예상 비용이 더 낮을 때만 Unnesting된 버전을 사용, 그렇지 않을 때는 원본 쿼리 그대로 필터 방식으로 최적화 한다.

1.1.1 UNNEST 힌트[편집]

서브쿼리를 Unnesting 함을써 조인방식으로 최적화하도록 유도.
  • 즉,서브쿼리를 메인쿼리절의 FROM절로 올리도록 쿼리를 변형한다.

1.1.2 NO_UNNEST 힌트[편집]

서브쿼리를 그대로 둔 상태에서 필터 방식으로 최적화 하도록 유도.

1.1.3 옵티마이저가 중첩해제를 못하는 경우[편집]

  1. ROWNUM 가상컬럼
  2. 집합 연산자 중 하나
  3. 중첩집계함수,서브쿼리의 외부(바깥) 쿼리 블록이 아닌 쿼리블록에 상호연관함수가 포함 된 계층적 서브쿼리 및 서브쿼리가 포함됩니다.

1.1.4 옵티마이저가 자동 중첩해제(UNNEST) 하는 경우[편집]

  1. 연관관계가 없는 IN 절의 하위 쿼리
  2. IN 과 EXISTS 의 연관된 서브쿼리, 집계 함수 또는 GROUP BY 절을 포함하지 않는 경우
  3. 옵티마이저에 추가서브쿼리 유형의 중첩을 해제하도록 지시하여 확장 서브쿼리 중첩해제를 활성화 할 수 있습니다.
    1. 서브쿼리에 HASH_AJ 또는 MERGE_AJ 힌트를 지정하여 상관되지 않은 NOT IN 서브쿼리의 중첩을 해제 할 수 있음.
    2. 서브쿼리에 UNNEST 힌트를 지정하여 다른 서브쿼리를 중첩 해제 할 수 있습니다.
  • 반대로 NO_UNNEST 힌트는 기존 서브쿼리 형태를 유지 하고 필터방식으로 실행계획이 수립되도록 하는 힌트임.
  • WHERE절에 사용되는 서브쿼리를 중첩 서브쿼리(Nested Subquery)라고 하며 IN, EXISTS 관계없이 메인쿼리에서 읽히는 FILTER방식으로 처리되어 메인레코드 하나 읽을 때마다 서브쿼리를 반복적으로 수행하면서 조건에 맞는 데이터를 추출하는 것이다.
  • 이러한 필터방식이 최적의 성능을 보장하지 않으므로 옵티마이저는 조인문으로 변경후 최적화(Unnesting) 하거나 메인과 서브쿼리를 별도의 SUB PLAN으로 분리하여 각각 최적화를 수행하는데 이때 서브쿼리에 FILTER 연산이 나타난다.
  • 서브 쿼리를 Unnesting 하지 않는다면 메인쿼리의 건 마다 서브쿼리를 반복 수행하는 FILTER 연산자를 사용하기에 Unnesting 힌트는 효율적으로 사용한다면 성능 향상을 가져온다.

1.1.5 UNNEST 같이 쓰는 힌트[편집]

  1. SWAP_JOIN_INPUTS : 해쉬테이블로 올릴 테이블 지정
  2. NO_SWAP_JOIN_INPUTS : 해쉬테이블로 올리지 않을 테이블 지정
  3. NL_SJ : NL SEMI JOIN 으로 수행 되도록 지시
  4. HASH_SJ SWAP_JOIN_INPUTS : HASH SEMI JOIN 으로 수행 되도록 지시 하고 서브쿼리를 먼저수행(해시테이블로) 되도록 지시함.
  5. HASH_SJ NO_SWAP_JOIN_INPUTS : HASH SEMI JOIN 으로 수행 되도록 지시 하고 서브쿼리를 먼저수행(해시테이블로) 되지 않도록 지시함.
  6. NL_AJ : NOT EXISTS 쿼리를 NL JOIN ANTI 로 수행 되도록 함.
  7. HASH_AJ : NOT EXISTS 쿼리를 HASH JOIN ANTI 로 수행 되도록 함.

1.2 뷰 Merging[편집]

1.3 조건절 Pushing[편집]

1.4 조건절 이행[편집]

1.5 공통 표현식 제거[편집]

1.6 outer 조인을 Inner 조인으로 변환[편집]

1.7 실체화 뷰 쿼리로 재작성[편집]

1.8 star 변환[편집]

1.9 outer 조인 뷰에 대한 조인 조건 Pushdown[편집]

1.10 or-expansion[편집]

2 쿼리 변환 두 가지 방식[편집]

2.1 휴리스틱 쿼리 변환[편집]

 : 결과만 보장된다면 무조건 쿼리 변환을 수행 

2.2 비용기반 쿼리 변환[편집]

 : 변환된 쿼리의 비용이 더 낮을 때만 그것을 사용하고, 그렇지 않을 때는 원본 쿼리 그대로 두고 최적화를 수행한다.