{panel:title = 어떻게 사용되나?} SQL에서 서브쿼리가 2개인 SQL을 실행하면 2개의 서브쿼리가 CSU(Complex Subquery Unnesting)를 수행하며 가능한 모든 경우의수는 아래와 같다. ※숫자표기법의 오른쪽의 정보는 참여한 쿼리블럭명, NEW라는 표시는 CSU에 의해서 새로 생성된 쿼리블럭 CBQT는 특성상 하나의 쿼리블럭과 또 다른 쿼리블럭이 만나 Transformaion이 수행되므로 쿼리블럭이 새로 생성된다 | (1,1) | NEW(SUBQ2), NEW(SUBQ1) |
(1,0) | NEW(SUBQ2), SUBQ1 --> NEW(SUBQ2)가 재사용되었다. | |
(0,1) | SUBQ2, NEW(SUBQ1) --> NEW(SUBQ1)이 재사용되었다. | |
(0,0) | SUBQ2, SUBQ1 --> SUBQ2와 SUBQ1이 재사용되었다. |
만약 CA가 없다면?
위의 예를 보면 각 쿼리블럭이 2번씩 사용되었다.
CA의 기능이 없다면 Cost를 구하는 연산을 두 번씩 실행해야 하지만 CA의 기능으로 부하를 감소시킬 수 있다.
중요한질문
Iteration에서 Transformation이 완료되고 변경된 SQL의 Cost만 구하면 되지않나?
왜 각각의 Iteration에서 전체SQL이 아닌 SQL의 특정부분(서브쿼리블럭)의 Cost를 구해야하나?
{panel:title = 중요한답변} 각 Iteration에서 개별 쿼리블럭의 Cost를 구하는 이유는 쿼리블럭의 Cost를 이용하여 Cut-off를 하기 위함. ex) Iteration1에서 Transformation이 끝나고 완성된 전체 SQL의 Cost가 100이라고 가정. Iteration2에서 전체 SQL이 아닌 서브쿼리블럭하나의 Cost가 200이라면 Iteration2의 Physical Optimization을 진행할 필요가 없어진다. 바로 Iteration2를 Skip하고 Iteration3으로 넘어갈 수 있다. Hard Parsing시 시간단축 |
|
{code:SQL | title= 10053 Trace에서 Cost Annotation이 사용되는 부분 | borderStyle=solid} ***************************** Cost-Based Subquery Unnesting ***************************** SU: Unnesting query blocks in query block MAIN (#1) that are valid to unnest. Subquery Unnesting on query block MAIN (#1)SU: Performing unnesting that does not require costing. SU: Considering subquery unnest on query block MAIN (#1). --> SU가 가능한지 Check함 SU: Checking validity of unnesting subquery SUBQ1 (#3) --> Costing 이 필요한 CSU 가 발생함 SU: Passed validity checks, but requires costing. SU: Checking validity of unnesting subquery SUBQ2 (#2) SU: Passed validity checks, but requires costing. SU: Using search type: exhaustive SU: Starting iteration 1, state space = (2,3) : (1,1) SU: Unnesting subquery query block SUBQ1 (#3)Subquery removal for query block SUBQ1 (#3) RSW: Not valid for subquery removal SUBQ1 (#3) Subquery unchanged. Registered qb: SEL$9F3C0132 0x805f7410 (SUBQ INTO VIEW FOR COMPLEX UNNEST SUBQ1) --> SEL$9F3C0132 : 새로만들어진 쿼리블록명 --> Iteration1에서 SUBQ1이 Unnestig 되어 서브쿼리가 VIew로 변환 {code} {code:SQL | title= trace | borderStyle=solid} SU: Costing transformed query. CBQT: Looking for cost annotations for query block SEL$9F3C0132,key=SEL$9F3C0132_00001002_3 --> View로 변환된 QB(SEL$9F3C0132)에 대해 Costing을 시도 CBQT: Could not find stored cost annotations. --> 위의 Key 값으로 CA를 찾지 못함 ...중간생략 kkoqbc: optimizing query block SEL$9F3C0132 (#3) --> CA를 찾지못했으므로 Costing(kkoqbc)이 진행 ...중간생략 Transfer Optimizer annotations for query block SEL$9F3C0132 (#3) --> 결과를 CA에 Key값으로저장(Transfer) Final cost for query block SEL$9F3C0132 (#3) - All Rows Plan: Best join order: 1 Cost: 515.3201 Degree: 1 Card: 918843.0000 Bytes: 7350744 ...중간생략 kkoqbc: finish optimizing query block SEL$9F3C0132 (#3) --> Costing을 마침 {code} {code:SQL | title= trace | borderStyle=solid}나 CBQT: Saved costed qb# 3 (SEL$9F3C0132), key = SEL$9F3C0132_00001002_3 --> 한번 저장된CA는 저장된 Cost를 이용하거나 ...중간생략 CA를 재사용하기위해서 Key값으로 CA주소를 찾아 CBQT: Looking for cost annotations for query block SEL$9F3C0132, key = SEL$9F3C0132_00001002_3 메모리 공간을 지울 수 있다 CBQT: Replaced cost annotations in query block SEL$9F3C0132. {code} * CA기능을 Control 하는 파라미터 : _optimizer_reuse_cost_annotations(default=true) |