본문 바로가기

Oracle Database SQL Tuning Guide 12c Release 2 (12.2)

Chapter07.Reading Execution Plans

7.1 Reading Execution Plans: Basic
이 섹션에서는 EXPLAIN PLAN 예제를 사용하여 실행 계획을 설명합니다.
다음 쿼리는 실행 계획을 표시합니다.
 
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL'statement_id','BASIC'));
이 명령문의 출력 예는 예 7-4 및 예제 7-1에 나와 있습니다.
 
Example 7-1 EXPLAIN PLAN for Statement ID ex_plan1
다음 플랜은 SELECT 문의 실행을 보여줍니다.
테이블 직원은 전체 테이블 스캔을 사용하여 액세스됩니다.
테이블 employee의 모든 행에 액세스하고 모든 행에 대해 WHERE 절 조건을 평가합니다.
 
EXPLAIN PLAN
SET statement_id = 'ex_plan1' FOR
SELECT phone_number
FROM employees
WHERE phone_number LIKE '650%';
---------------------------------------
| Id | Operation          | Name           |
---------------------------------------
| 0  | SELECT STATEMENT |                |
| 1  | TABLE ACCESS FULL | EMPLOYEES    |
---------------------------------------
예 7-2 명령문 ID ex_plan2에 대한 EXPLAIN PLAN
이 다음 계획은 SELECT 문의 실행을 보여줍니다.
이 예에서 데이터베이스 범위는 EMP_NAME_IX 인덱스를 검색하여 WHERE 절 조건을 평가합니다.
 
EXPLAIN PLAN
SET statement_id = 'ex_plan2' FOR
SELECT last_name
FROM employees
WHERE last_name LIKE 'Pe%';
 
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL'ex_plan2','BASIC'));
----------------------------------------
| Id | Operation         | Name            |
----------------------------------------
| 0 | SELECT STATEMENT  |               |
| 1 | INDEX RANGE SCAN    | EMP_NAME_IX  |
----------------------------------------
 
7.2 Reading Execution Plans: Advanced
 
7.2.1 Reading Adaptive Query Plans
적응 형 옵티 마이저는 런타임 통계를 기반으로 계획을 조정할 수있는 옵티 마이저의 기능입니다.
모든 적응 메커니즘은 기본 계획과 다른 진술에 대한 최종 계획을 실행할 수 있습니다.
적응 형 쿼리 계획은 현재 문이 실행되는 동안 하위 계획 중에서 선택합니다.
반대로, 자동 재 최적화는 현재 명령문 실행 이후에 발생하는 실행에 대해서만 계획을 변경합니다.
데이터베이스가 계획의 Notes 섹션에있는 주석을 기반으로 SQL 문에 대한 적응형 쿼리 최적화를 사용하는지 여부를 결정할 수 있습니다.
주석은 행 소스가 동적인지 또는 자동 재 최적화가 계획을 채택하는지 여부를 나타냅니다.
 
Assumptions
이 자습서에서는 다음을 가정합니다.
• STATISTICS_LEVEL 초기화 매개 변수가 ALL로 설정됩니다.
• 데이터베이스는 적응 실행을위한 기본 설정을 사용합니다.
• 사용자 oe로서 다음 별도의 쿼리를 실행하려고합니다.
 
SELECT o.order_id, v.product_name
FROM orders o,
SELECT order_id, product_name
FROM order_items o, product_information p
WHERE p.product_id = o.product_id
AND list_price < 50
AND min_price < 40 ) v
WHERE o.order_id = v.order_id
SELECT product_name
FROM order_items o, product_information p
WHERE o.unit_price = 15
AND quantity > 1
AND p.product_id = o.product_id
 
• 각 쿼리를 실행하기 전에 DBMS_XPLAN.DISPLAY_PLAN을 쿼리하여 기본 계획, 즉 적응 메커니즘을 적용하기 전에 
옵티마이저가 선택한 계획을 확인하려고합니다.
각 쿼리를 실행 한 후 DBMS_XPLAN.DISPLAY_CURSOR를 쿼리하여 최종 계획과 적응 쿼리 계획을 확인합니다.
• SYS는 oe에게 다음 권한을 부여했습니다.
– GRANT SELECT ON V_$SESSION TO oe
– GRANT SELECT ON V_$SQL TO oe
– GRANT SELECT ON V_$SQL_PLAN TO oe
– GRANT SELECT ON V_$SQL_PLAN_STATISTICS_ALL TO oe
 
적응 최적화의 결과를 보려면 다음을 수행하십시오.
1. SQL * Plus를 시작한 다음 사용자 oe로 데이터베이스에 연결하십시오.
 
2. 질의 명령. 예를 들어, 다음 문을 사용하십시오.
SELECT o.order_id, v.product_name
FROM orders o,
SELECT order_id, product_name
FROM order_items o, product_information p
WHERE p.product_id = o.product_id
AND list_price < 50
AND min_price < 40 ) v
WHERE o.order_id = v.order_id;
 
3. 커서로 계획을 봅니다.
예를 들어, 다음 명령을 실행하십시오.
SET LINESIZE 165
SET PAGESIZE 0
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'+ALLSTATS'));
 
다음 샘플 출력은 페이지에 맞게 다시 포맷되었습니다.
이 계획에서 최적화 알고리즘은 중첩 루프 조인을 선택합니다.
원래의 옵티 마이저 추정치는 E-Rows 컬럼에 표시되는 반면 실행 중 수집 된 실제 통계는 A-Rows 컬럼에 표시됩니다.
MERGE JOIN 작업에서 예상 행 수와 실제 행 수의 차이가 중요합니다.
--------------------------------------------------------------------------------------------
|Id| Operation | Name |Start|E-Rows|A-Rows|A-Time|Buff|OMem|1Mem|O/1/M|
--------------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | | 1| | 269|00:00:00.09|1338| | | |
| 1| NESTED LOOPS | | 1| 1| 269|00:00:00.09|1338| | | |
| 2| MERGE JOIN CARTESIAN| | 1| 4|9135|00:00:00.03| 33| | | |
|*3| TABLE ACCESS FULL |PRODUCT_INFORMAT| 1| 1| 87|00:00:00.01| 32| | | |
| 4| BUFFER SORT | | 87|105|9135|00:00:00.01| 1|4096|4096|1/0/0|
| 5| INDEX FULL SCAN | ORDER_PK | 1|105| 105|00:00:00.01| 1| | | |
|*6| INDEX UNIQUE SCAN | ORDER_ITEMS_UK |9135| 1| 269|00:00:00.03|1305| | | |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(("MIN_PRICE"<40 AND "LIST_PRICE"<50))
6 - access("O"."ORDER_ID"="ORDER_ID" AND "P"."PRODUCT_ID"="O"."PRODUCT_ID")
 
4. 2 단계에서 실행 한 동일한 주. 조회를 실행하십시오.
 
5. 3 단계에서 실행 한 동일한 SELECT 문을 사용하여 커서에서 실행 계획을 봅니다.
다음 예제에서는 최적화 프로그램이 해시 조인을 사용하여 다른 계획을 선택했음을 보여줍니다.
참고 섹션에서는 옵티마이 저가 통계 피드백을 사용하여 쿼리의 두 번째 실행에 대한 비용 견적을 
조정하여 자동 재 최적화를 보여줍니다.
--------------------------------------------------------------------------------------------
|Id| Operation |Name |Start|E-Rows|A-Rows|A-Time|Buff|Reads|OMem|1Mem|O/1/M|
--------------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | | 1 | |269|00:00:00.02|60|1| | | |
| 1| NESTED LOOPS | | 1 |269|269|00:00:00.02|60|1| | | |
|*2| HASH JOIN | | 1 |313|269|00:00:00.02|39|1|1000K|1000K|1/0/0|
|*3| TABLE ACCESS FULL |PRODUCT_INFORMA| 1 | 87| 87|00:00:00.01|15|0| | | |
| 4| INDEX FAST FULL SCAN|ORDER_ITEMS_UK | 1 |665|665|00:00:00.01|24|1| | | |
|*5| INDEX UNIQUE SCAN |ORDER_PK |269| 1|269|00:00:00.01|21|0| | | |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID")
3 - filter(("MIN_PRICE"<40 AND "LIST_PRICE"<50))
5 - access("O"."ORDER_ID"="ORDER_ID")
Note
-----
- statistics feedback used for this statement
 
6. V$SQL을 쿼리하여 성능 향상을 확인하십시오.
다음 쿼리는 두 문 (샘플 출력 포함)의 성능을 보여줍니다.
SELECT CHILD_NUMBER, CPU_TIME, ELAPSED_TIME, BUFFER_GETS
FROM V$SQL
WHERE SQL_ID = 'gm2npz344xqn8';
CHILD_NUMBER CPU_TIME ELAPSED_TIME BUFFER_GETS
------------ ---------- ------------ -----------
0 92006 131485 1831
1 12000 24156 60
 
실행 된 두 번째 명령문 (하위 번호 1)은 통계 피드백을 사용했습니다.
CPU 시간, 경과 시간 및 버퍼 가져 오기가 모두 상당히 낮습니다.
 
7. order_items 조회에 대한 계획을 설명하십시오.
예를 들어, 다음 문을 사용하십시오.
EXPLAIN PLAN FOR
SELECT product_name
FROM order_items o, product_information p
WHERE o.unit_price = 15
AND quantity > 1
AND p.product_id = o.product_id;
 
8. 계획 테이블에서 계획을보십시오.
예를 들어, 다음 문을 실행하십시오.
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Sample output appears below:
-------------------------------------------------------------------------------
|Id| Operation | Name |Rows|Bytes|Cost (%CPU)|Time|
-------------------------------------------------------------------------------
| 0| SELECT STATEMENT | |4|128|7 (0)|00:00:01|
| 1| NESTED LOOPS | | | | | |
| 2| NESTED LOOPS | |4|128|7 (0)|00:00:01|
|*3| TABLE ACCESS FULL |ORDER_ITEMS |4|48 |3 (0)|00:00:01|
|*4| INDEX UNIQUE SCAN |PRODUCT_INFORMATION_PK|1| |0 (0)|00:00:01|
| 5| TABLE ACCESS BY INDEX ROWID|PRODUCT_INFORMATION |1|20 |1 (0)|00:00:01|
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("O"."UNIT_PRICE"=15 AND "QUANTITY">1)
4 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID")
 
이 계획에서 최적화 알고리즘은 중첩 루프 조인을 선택합니다.
 
9. 이전에 설명한 쿼리를 실행합니다.
예를 들어, 다음 문을 사용하십시오.
SELECT product_name
FROM order_items o, product_information p
WHERE o.unit_price = 15
AND quantity > 1
AND p.product_id = o.product_id;
 
10. 커서에서 계획을보십시오.
예를 들어, 다음 명령을 실행하십시오.
SET LINESIZE 165
SET PAGESIZE 0
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(FORMAT=>'+ADAPTIVE'));
 
샘플 출력은 아래에 나와 있습니다. 실행시 수집 된 통계 (4 단계)에 따라 최적화 프로그램은 중첩 루프 조인이 아니라 해시 조인을 선택했습니다.
대시 (-)는 최적화 알고리즘이 고려했지만 궁극적으로 선택하지 않는 중첩 루프 계획의 단계를 나타냅니다.
스위치는 적응 형 쿼리 계획 기능을 보여줍니다.
-------------------------------------------------------------------------------
|Id | Operation | Name |Rows|Bytes|Cost(%CPU)|Time |
-------------------------------------------------------------------------------
| 0| SELECT STATEMENT | |4|128|7(0)|00:00:01|
| *1| HASH JOIN | |4|128|7(0)|00:00:01|
|- 2| NESTED LOOPS | | | | | |
|- 3| NESTED LOOPS | | |128|7(0)|00:00:01|
|- 4| STATISTICS COLLECTOR | | | | | |
| *5| TABLE ACCESS FULL | ORDER_ITEMS |4| 48|3(0)|00:00:01|
|-*6| INDEX UNIQUE SCAN | PRODUCT_INFORMATI_PK|1| |0(0)|00:00:01|
|- 7| TABLE ACCESS BY INDEX ROWID| PRODUCT_INFORMATION |1| 20|1(0)|00:00:01|
| 8| TABLE ACCESS FULL | PRODUCT_INFORMATION |1| 20|1(0)|00:00:01|
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID")
5 - filter("O"."UNIT_PRICE"=15 AND "QUANTITY">1)
6 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID")
Note
-----
- this is an adaptive plan (rows marked '-' are inactive)
 
7.2.2 Viewing Parallel Execution with EXPLAIN PLAN
병렬 쿼리 계획은 직렬 쿼리 계획과 중요한 점에서 다릅니다.
 
7.2.2.1 About EXPLAIN PLAN and Parallel Queries
병렬 쿼리 튜닝은 구동 테이블을 선택하여 비 병렬 쿼리 튜닝 연습과 매우 비슷합니다.
그러나 선택을 관리하는 규칙은 다릅니다.
일련의 경우, 최상의 운전 테이블은 제한 조건을 적용한 후 가장 적은 수의 행을 생성합니다.
데이터베이스는 고유하지 않은 색인을 사용하여 더 작은 테이블을 더 큰 테이블에 조인합니다.
예를 들어 고객, 계정 및 트랜잭션으로 구성된 테이블 계층 구조를 생각해보십시오.
Figure 7-1 A Table Hierarchy
 
이 예에서 고객은 가장 작은 테이블이지만 트랜잭션은 가장 큰 테이블입니다.
일반적인 OLTP 쿼리는 특정 고객 계정에 대한 트랜잭션 정보를 검색합니다.
조회는 고객 테이블에서 실행됩니다.
목표는 논리적 I / O를 최소화하는 것이며, 일반적으로 물리적 I/O 및 CPU 시간을 비롯한 기타 중요한 리소스를 최소화합니다.
병렬 쿼리의 경우 일반적으로 운전 표가 가장 큰 표입니다.
이 경우 병렬 쿼리를 사용하는 것은 효율적이지 않습니다. 각 테이블의 몇 행에 액세스하기 때문입니다.
그러나 지난 달 특정 유형의 거래가 있었던 모든 고객을 식별해야하는 경우 어떻게해야합니까?
고객 테이블에 제한 조건이 없기 때문에 트랜잭션 테이블에서 운전하는 것이 더 효율적입니다.
데이터베이스는 트랜잭션 테이블의 행과 계정 테이블을 조인 한 다음 최종적으로 결과 테이블을 고객 테이블에 조인합니다.
이 경우, 계정 및 고객 테이블에 사용되는 것은 아마도 첫 번째 쿼리에서 사용 된 고유하지 않은 인덱스가 아닌 
매우 선택적인 기본 키 또는 고유 인덱스입니다.
트랜잭션 테이블이 크고 컬럼이 선택적이지 않으므로 트랜잭션 테이블에서 병렬 쿼리 구동을 사용하는 것이 좋습니다.
병렬 작업에는 다음이 포함됩니다.
• PARALLEL_TO_PARALLEL
• PARALLEL_TO_SERIAL
PARALLEL_TO_SERIAL 연산은 항상 쿼리 코디네이터가 병렬 연산에서 행을 소비 할 때 발생하는 단계입니다.
이 쿼리에서 발생하지 않는 또 다른 유형의 조작은 SERIAL 조작입니다.
이러한 유형의 작업이 발생하면 병목 현상이 발생할 수 있으므로 성능을 향상시키기 위해 병렬 작업을 수행하는 것이 좋습니다.
• PARALLEL_FROM_SERIAL
• PARALLEL_TO_PARALLEL
각 단계의 작업 부하가 상대적으로 동일하면 일반적으로 PARALLEL_TO_PARALLEL 연산이 최상의 성능을 발휘합니다.
• PARALLEL_COMBINED_WITH_CHILD
• PARALLEL_COMBINED_WITH_PARENT
PARALLEL_COMBINED_WITH_PARENT 조작은 데이터베이스가 상위 단계와 동시에 단계를 수행 할 때 발생합니다.
병렬 단계가 많은 행을 생성하면 QC가 생성 된만큼 빠르게 행을 소비하지 못할 수도 있습니다.
이 상황을 개선하기 위해 거의 수행 할 수 없습니다.
 
7.2.2.2 Viewing Parallel Queries with EXPLAIN PLAN: Example
병렬 쿼리와 함께 EXPLAIN PLAN을 사용할 때 데이터베이스는 하나의 병렬 계획을 컴파일하고 실행합니다.
이 계획은 QC 계획에서 병렬 지원에 고유 한 행 소스를 할당하여 직렬 계획에서 파생됩니다.
두 개의 병렬 실행 서버 세트 PQ 모델에 필요한 테이블 대기열 행 소스 (PX 전송 및 PX 수신),과 립 반복기 및 버퍼 정렬은 
병렬 계획에 직접 삽입됩니다.
이 계획은 모든 병렬 실행 서버가 병렬로 실행될 때나 연속적으로 실행될 때 QC와 동일한 계획입니다.
 
Example 7-3 Parallel Query Explain Plan
다음의 간단한 예제는 병렬 쿼리에 대한 EXPLAIN PLAN을 보여줍니다.
 
CREATE TABLE emp2 AS SELECT * FROM employees;
ALTER TABLE emp2 PARALLEL 2;
EXPLAIN PLAN FOR
SELECT SUM(salary)
FROM emp2
GROUP BY department_id;
 
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows| Bytes |Cost %CPU| TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 107 | 2782 | 3 (34| | | |
| 1 | PX COORDINATOR | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 107 | 2782 | 3 (34| Q1,01 | P->| QC (RAND) |
| 3 | HASH GROUP BY | | 107 | 2782 | 3 (34| Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 107 | 2782 | 3 (34| Q1,01 | PCWP | |
| 5 | PX SEND HASH | :TQ10000 | 107 | 2782 | 3 (34| Q1,00 | P->| HASH |
| 6 | HASH GROUP BY | | 107 | 2782 | 3 (34| Q1,00 | PCWP | |
| 7 | PX BLOCK ITERATOR | | 107 | 2782 | 2 (0| Q1,00 | PCWP | |
| 8 | TABLE ACCESS FULL| EMP2 | 107 | 2782 | 2 (0| Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------
 
한 세트의 병렬 실행 서버가 EMP2를 병렬로 검색하고 두 번째 세트는 GROUP BY 작업에 대한 집계를 수행합니다.
PX BLOCK ITERATOR 행 소스는 테이블 EMP2를 조각으로 나누어 병렬 실행 서버간에 스캔 작업 부하를 나누는 것을 나타냅니다.
PX SEND 및 PX RECEIVE 행 소스는 병렬 스캔에서 행이 위로 이동하고 HASH 테이블 대기열을 통해 다시 분할 된 다음 상단 집합에서 
읽고 집계 될 때 두 병렬 실행 서버 세트를 연결하는 파이프를 나타냅니다.
PX SEND QC 행 소스는 무작위 (RAND) 순서로 QC에 전송되는 집계 값을 나타냅니다.
PX COORDINATOR 행 소스는 계획 트리에서 그 아래에 나타나는 병렬 계획을 제어하고 예약하는 QC 또는 쿼리 코디네이터를 나타냅니다.
 
7.2.3 Viewing Bitmap Indexes with EXPLAIN PLAN
비트 맵 인덱스를 사용하는 인덱스 행 소스는 인덱스 유형을 나타내는 BITMAP이라는 단어와 함께 EXPLAIN PLAN 출력에 나타납니다.
 
Note:
비트 맵 조인 인덱스를 사용하는 쿼리는 비트 맵 조인 인덱스 액세스 경로를 나타냅니다.
비트 맵 조인 인덱스의 작업은 비트 맵 인덱스와 동일합니다.
보기 7-4 비트 맵 인덱스가있는 EXPLAIN PLAN
이 예에서 술어 c1 = 2는 빼기가 발생할 수있는 비트 맵을 생성합니다.
이 비트 맵에서 c2 = 6에 대한 비트 맵의 비트를 뺍니다.
또한 계획에 두 개의 MINUS 행 소스가있는 이유를 설명하는 c2 IS NULL의 비트 맵 비트가 공제됩니다.
열에 NOT NULL 제약 조건이 없으면 의미 감수성을 위해 NULL 빼기가 필요합니다.
TO ROWIDS 옵션은 테이블 액세스에 필요한 ROWID를 생성합니다.
 
EXPLAIN PLAN FOR SELECT *
FROM t
WHERE c1 = 2
AND c2 <> 6
OR c3 BETWEEN 10 AND 20;
 
SELECT STATEMENT
    TABLE ACCESS T BY INDEX ROWID
        BITMAP CONVERSION TO ROWID
            BITMAP OR
                BITMAP MINUS
                    BITMAP MINUS
                        BITMAP INDEX C1_IND SINGLE VALUE
                        BITMAP INDEX C2_IND SINGLE VALUE
                    BITMAP INDEX C2_IND SINGLE VALUE
                BITMAP MERGE
                    BITMAP INDEX C3_IND RANGE SCAN
 
7.2.4 Viewing Result Cache with EXPLAIN PLAN
쿼리에 result_cache 힌트가 포함되어 있으면 ResultCache 연산자가 실행 계획에 삽입됩니다.
예를 들어, 다음 쿼리를 고려하십시오.
SELECT /*+ result_cache */ deptno, avg(sal)
FROM emp
GROUP BY deptno;
 
이 쿼리에 대한 EXPLAIN PLAN을 보려면 다음 명령을 사용하십시오.
EXPLAIN PLAN FOR
SELECT /*+ result_cache */ deptno, avg(sal)
FROM emp
GROUP BY deptno;
 
SELECT PLAN_TABLE_OUTPUT FROM TABLE (DBMS_XPLAN.DISPLAY());
 
이 쿼리에 대한 EXPLAIN PLAN 출력은 다음과 유사해야합니다.
--------------------------------------------------------------------------------
|Id| Operation | Name |Rows|Bytes|Cost(%CPU)|Time |
--------------------------------------------------------------------------------
|0| SELECT STATEMENT | | 11 | 77 | 4 (25)| 00:00:01|
|1| RESULT CACHE |b06ppfz9pxzstbttpbqyqnfbmy| | | | |
|2| HASH GROUP BY | | 11 | 77 | 4 (25)| 00:00:01|
|3| TABLE ACCESS FULL| EMP |107 | 749| 3 (0| 00:00:01|
--------------------------------------------------------------------------------
 
이 EXPLAIN PLAN에서 ResultCache 연산자는 CacheId (b06ppfz9pxzstbttpbqyqnfbmy)로 식별됩니다.
이제이 CacheId를 사용하여 V $ RESULT_CACHE_OBJECTS 뷰에 대한 조회를 실행할 수 있습니다.
 
7.2.5 Viewing Partitioned Objects with EXPLAIN PLAN
EXPLAIN PLAN을 사용하여 Oracle Database가 특정 쿼리에 대해 분할 된 오브젝트에 액세스하는 방법을 확인하십시오.
프 i 이후 액세스 된 파티션은 PARTITION START 및 PARTITION STOP 컬럼에 표시됩니다.
| 위 파티션의 행 소스 이름은 PARTITION RANGE입니다.
해시 파티션의 경우, 행 소스 이름은 PARTITION HASH입니다.
조인은 조인 된 테이블 중 하나의 계획 테이블의 DISTRIBUTION 컬럼에 PARTITION(KEY)이 들어있는 경우 
부분 파티션 와이즈 조인을 사용하여 구현됩니다.
조인 된 테이블 중 하나가 조인 열로 분할되고 테이블이 병렬 처리되는 경우 부분적으로 파티션 방식의 조인이 가능합니다.
파티션 행 소스가 EXPLAIN PLAN 출력의 조인 행 소스 앞에 나타나는 경우 전체 파티션 와이즈 조인을 사용하여 조인이 구현됩니다.
두 개의 조인 된 테이블이 각각의 조인 열에 동일하게 분할 된 경우에만 전체 파티션 방식의 조인이 가능합니다.
몇 가지 유형의 파티셔닝을위한 실행 계획의 예는 다음과 같습니다.
 
7.2.5.1 Displaying Range and Hash Partitioning with EXPLAIN PLAN: Examples
가지 치기가 표시되는 방법을 설명하기 위해 hire_date에서 범위별로 분할 된 다음 표 emp_range를 고려하십시오.
Oracle Database 샘플 스키마의 직원 및 부서 테이블이 있다고 가정합니다.
 
CREATE TABLE emp_range
PARTITION BY RANGE(hire_date)
(PARTITION emp_p1 VALUES LESS THAN (TO_DATE('1-JAN-1992','DD-MON-YYYY')),
PARTITION emp_p2 VALUES LESS THAN (TO_DATE('1-JAN-1994','DD-MON-YYYY')),
PARTITION emp_p3 VALUES LESS THAN (TO_DATE('1-JAN-1996','DD-MON-YYYY')),
PARTITION emp_p4 VALUES LESS THAN (TO_DATE('1-JAN-1998','DD-MON-YYYY')),
PARTITION emp_p5 VALUES LESS THAN (TO_DATE('1-JAN-2001','DD-MON-YYYY')))
AS SELECT * FROM employees;
 
첫 번째 예제의 경우 다음 문을 고려하십시오.
EXPLAIN PLAN FOR
SELECT * FROM emp_range;
Oracle Database는 다음과 비슷한 것을 표시합니다.
--------------------------------------------------------------------
|Id| Operation | Name |Rows| Bytes|Cost|Pstart|Pstop|
--------------------------------------------------------------------
| 0| SELECT STATEMENT | | 105| 13965 | 2 | | |
| 1| PARTITION RANGE ALL| | 105| 13965 | 2 | 1 | 5 |
| 2| TABLE ACCESS FULL | EMP_RANGE | 105| 13965 | 2 | 1 | 5 |
--------------------------------------------------------------------
데이터베이스는 테이블 액세스 행 원본 위에 파티션 행 소스를 작성합니다.
액세스 할 파티션 세트를 반복합니다.
이 예에서, 파티션 반복자는 모든 파티션 (ALL 옵션)을 처리합니다. 이는 술어가 제거에 사용되지 않았기 때.입니다.
PLAN_TABLE의 PARTITION_START 및 PARTITION_STOP 열은 1에서 5까지의 모든 파티션에 대한 액세스를 표시합니다.
다음 예제의 경우 다음 문을 고려하십시오.
EXPLAIN PLAN FOR
SELECT *
FROM emp_range
WHERE hire_date >= TO_DATE('1-JAN-1996','DD-MON-YYYY');
-----------------------------------------------------------------------
| Id | Operation | Name |Rows|Bytes|Cost|Pstart|Pstop|
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 399 | 2 | | |
| 1 | PARTITION RANGE ITERATOR| | 3 | 399 | 2 | 4 | 5 |
| *2 | TABLE ACCESS FULL |EMP_RANGE| 3 | 399 | 2 | 4 | 5 |
-----------------------------------------------------------------------
 
앞의 예에서 hire_date에 대한 술어를 사용하여 다른 파티션을 프룬(prune)하기 때문에 파티션 행 소스는 파티션 4에서 5로 반복됩니다.
마지막으로, 다음 진술을 고려하십시오.
EXPLAIN PLAN FOR
SELECT *
FROM emp_range
WHERE hire_date < TO_DATE('1-JAN-1992','DD-MON-YYYY');
-----------------------------------------------------------------------
| Id | Operation | Name |Rows|Bytes|Cost|Pstart|Pstop|
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 133 | 2 | | |
| 1 | PARTITION RANGE SINGLE| | 1 | 133 | 2 | 1 | 1 |
|* 2 | TABLE ACCESS FULL | EMP_RANGE | 1 | 133 | 2 | 1 | 1 |
-----------------------------------------------------------------------
 
앞의 예에서 컴파일 타임에 파티션 1 만 액세스하고 알 수 있습니다. 따라서 파티션 행 소스가 필요하지 않습니다.
 
Note:
Oracle Database는 파티션 행 원본 이름이 PARTITION RANGE 대신 PARTITION HASH 인 것을 제외하고 
해시 파티션 된 개체에 대해 동일한 정보를 표시합니다.
또한 해시 파티셔닝을 사용하면 동등성 또는 IN-list 술어 만 사용하여 프 i을 수행 할 수 있습니다.
 
7.2.5.2 Pruning Information with Composite Partitioned Objects: Examples
Oracle Database가 복합 분할 객체에 대한 프 루닝 정보를 표시하는 방법을 설명하려면 emp_comp 테이블을 고려하십시오.
그것은 hiredate에서 range-partitioned이며 deptno에서 해시에 의해 서브 파티셔닝됩니다.
 
CREATE TABLE emp_comp PARTITION BY RANGE(hire_date)
SUBPARTITION BY HASH(department_id) SUBPARTITIONS 3
(PARTITION emp_p1 VALUES LESS THAN (TO_DATE('1-JAN-1992','DD-MON-YYYY')),
PARTITION emp_p2 VALUES LESS THAN (TO_DATE('1-JAN-1994','DD-MON-YYYY')),
PARTITION emp_p3 VALUES LESS THAN (TO_DATE('1-JAN-1996','DD-MON-YYYY')),
PARTITION emp_p4 VALUES LESS THAN (TO_DATE('1-JAN-1998','DD-MON-YYYY')),
PARTITION emp_p5 VALUES LESS THAN (TO_DATE('1-JAN-2001','DD-MON-YYYY')))
AS SELECT * FROM employees;
 
첫 번째 예제의 경우 다음 문을 고려하십시오.
EXPLAIN PLAN FOR
SELECT * FROM emp_comp;
-----------------------------------------------------------------------
|Id| Operation | Name | Rows | Bytes |Cost|Pstart|Pstop|
-----------------------------------------------------------------------
| 0| SELECT STATEMENT | | 10120 | 1314K| 78 | | |
| 1| PARTITION RANGE ALL| | 10120 | 1314K| 78 | 1 | 5 |
| 2| PARTITION HASH ALL| | 10120 | 1314K| 78 | 1 | 3 |
| 3| TABLE ACCESS FULL| EMP_COMP | 10120 | 1314K| 78 | 1 | 15 |
-----------------------------------------------------------------------
 
이 예제는 Oracle Database가 복합 오브젝트의 모든 파티션의 모든 하위 파티션에 액세스 할 때의 계획을 보여줍니다.
데이터베이스는 파티션을 대상으로 반복되는 범위 파티션 행 소스와 액세스 된 각 파티션의 하위 파티션을 반복하는 
해시 파티션 행 소스라는 두 가지 파티션 행 원본을이 용도로 사용합니다.
다음 예에서 범위 파티션 행 소스는 파티션 1에서 5로 반복합니다. 데이터베이스가 제거를 수행하지 않기 때문입니다.
각 파티션 내에서 해시 파티션 행 소스는 현재 파티션의 하위 파티션 1 - 3을 반복합니다.
결과적으로 테이블 액세스 행 원본은 하위 파티션 1 - 15에 액세스합니다.
즉, 데이터베이스는 복합 오브젝트의 모든 서브 파티션에 액세스합니다.
 
EXPLAIN PLAN FOR
SELECT *
FROM emp_comp
WHERE hire_date = TO_DATE('15-FEB-1998''DD-MON-YYYY');
-----------------------------------------------------------------------
| Id | Operation | Name |Rows|Bytes |Cost|Pstart|Pstop|
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 20 | 2660 | 17 | | |
| 1 | PARTITION RANGE SINGLE| | 20 | 2660 | 17 | 5 | 5 |
| 2 | PARTITION HASH ALL | | 20 | 2660 | 17 | 1 | 3 |
|* 3 | TABLE ACCESS FULL | EMP_COMP | 20 | 2660 | 17 | 13 | 15 |
-----------------------------------------------------------------------
 
앞의 예에서 마지막 파티션 인 파티션 5 만 액세스됩니다.
이 파티션은 컴파일시에 알려 지므로 데이터베이스는 계획에서이 파티션을 표시 할 필요가 없습니다.
해시 파티션 행 소스는 해당 파티션 내의 모든 서브 파티션에 대한 액세스를 보여줍니다. 
즉, 서브 파티션 1 - 3은 emp_comp 테이블의 서브 파티션 13 - 15로 변환됩니다.
이제 다음 내용을 고려하십시오.
EXPLAIN PLAN FOR
SELECT *
FROM emp_comp
WHERE department_id = 20;
------------------------------------------------------------------------
| Id | Operation |Name |Rows | Bytes |Cost|Pstart|Pstop|
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 101 | 13433 | 78 | | |
| 1 | PARTITION RANGE ALL | | 101 | 13433 | 78 | 1 | 5 |
| 2 | PARTITION HASH SINGLE| | 101 | 13433 | 78 | 3 | 3 |
|* 3 | TABLE ACCESS FULL | EMP_COMP | 101 | 13433 | 78 | | |
------------------------------------------------------------------------
 
이전 예에서 술어 deptno = 20은 각 파티션 내의 해시 차원에서 프룬(prune)을 가능하게합니다.
따라서 Oracle Database는 단일 하위 파티션에만 액세스해야합니다.
이 서브 파티션의 수는 컴파일시 알려 지므로 해시 파티션 행 소스는 필요하지 않습니다.
마지막으로, 다음 진술을 고려하십시오.
VARIABLE dno NUMBER;
EXPLAIN PLAN FOR
SELECT *
FROM emp_comp
WHERE department_id =:dno;
-----------------------------------------------------------------------
| Id| Operation | Name |Rows| Bytes |Cost|Pstart|Pstop|
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 101| 13433 | 78 | | |
| 1 | PARTITION RANGE ALL | | 101| 13433 | 78 | 1 | 5 |
| 2 | PARTITION HASH SINGLE| | 101| 13433 | 78 | KEY | KEY |
|*3 | TABLE ACCESS FULL | EMP_COMP | 101| 13433 | 78 | | |
-----------------------------------------------------------------------
 
마지막 두 예제는 department_id =:dno가 deptno=20을 대체한다는 점을 제외하고는 동일합니다.
이 마지막 경우, 서브 파티션 번호는 컴파일시 알 수 없으며 해시 파티션 행 소스가 할당됩니다.
Oracle Database는 각 분할 영역 내에서 하나의 하위 분할 영역에만 액세스하기 때문에이 행 소스에 대해 옵션은 SINGLE입니다.
 
2 단계에서 PARTITION_START 및 PARTITION_STOP 모두 KEY로 설정됩니다.
이 값은 Oracle Database가 런타임에 하위 파티 션 수를 결정한다는 의미입니다.
 
7.2.5.3 Examples of Partial Partition-Wise Joins
예제 7-5와 예제 7-6 모두에서 쿼리 최적화 프로그램이이 쿼리의 비용을 기반으로 다른 계획을 선택할 수 있으므로 
PQ_DISTRIBUTE 힌트가 명시 적으로 부분 파티션 방식의 조인을 강제로 수행합니다.
 
Example 7-5 Partial Partition-Wise Join with Range Partition
다음 예제에서 데이터베이스는 분할 열 department_id의 emp_range_did를 조인하고 병렬화합니다.
dept2 테이블이 분할되지 않았기 때문에 데이터베이스는 부분적인 분할 조인을 사용할 수 있습니다.
Oracle Database는 조인 전에 dept2 테이블을 동적으로 분할합니다.
CREATE TABLE dept2 AS SELECT * FROM departments;
 
ALTER TABLE dept2 PARALLEL 2;
CREATE TABLE emp_range_did PARTITION BY RANGE(department_id)
(PARTITION emp_p1 VALUES LESS THAN (150),
PARTITION emp_p5 VALUES LESS THAN (MAXVALUE) )
AS SELECT * FROM employees;
ALTER TABLE emp_range_did PARALLEL 2;
 
EXPLAIN PLAN FOR
SELECT /*+ PQ_DISTRIBUTE(d NONE PARTITION) ORDERED */ e.last_name,
d.department_name
FROM emp_range_did e, dept2 d
WHERE e.department_id = d.department_id;
------------------------------------------------------------------------------------------------
|Id| Operation |Name |Row|Byte|Cost|Pstart|Pstop|TQ|IN-OUT|PQ Distrib|
------------------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | |284 |16188|6 | | | | | |
| 1| PX COORDINATOR | | | | | | | | | |
| 2| PX SEND QC (RANDOM) |:TQ10001 |284 |16188|6 | | | Q1,01 |P->|QC (RAND) |
|*3| HASH JOIN | |284 |16188|6 | | | Q1,01 |PCWP | |
| 4| PX PARTITION RANGE ALL | |284 |7668 |2 | 1 | 2 | Q1,01 |PCWC | |
| 5| TABLE ACCESS FULL |EMP_RANGE_DID|284 |7668 |2 | 1 | 2 | Q1,01 |PCWP | |
| 6| BUFFER SORT | | | | | | | Q1,01 |PCWC | |
| 7| PX RECEIVE | | 21 | 630 |2 | | | Q1,01 |PCWP | |
| 8| PX SEND PARTITION (KEY)|:TQ10000 | 21 | 630 |2 | | | |S->|PART (KEY)|
| 9| TABLE ACCESS FULL |DEPT2 | 21 | 630 |2 | | | | | |
------------------------------------------------------------------------------------------------
 
실행 계획은 테이블 dept2가 순차적으로 스캔되고 emp_range_did (department_id)의 동일한 분할 열 값을 갖는 
모든 행이 PART (KEY) 또는 분할 키, 테이블 대기열을 통해 부분 분할 파티션 와이즈 조인을 수행하는 동일한 
병렬 실행 서버로 전송됨을 보여줍니다.
 
Example 7-6 Partial Partition-Wise Join with Composite Partition
다음 예에서 emp_comp는 분할 열에서 조인되고 병렬 처리되므로 dept2가 분할되지 않았기 때문에 
부분 분할 방식의 분할 조인을 사용할 수 있습니다.
데이터베이스는 결합 전에 dept2를 동적으로 분할합니다.
ALTER TABLE emp_comp PARALLEL 2;
 
EXPLAIN PLAN FOR
SELECT /*+ PQ_DISTRIBUTE(d NONE PARTITION) ORDERED */ e.last_name, d.department_name
FROM emp_comp e, dept2 d
WHERE e.department_id = d.department_id;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
------------------------------------------------------------------------------------------------
| Id| Operation | Name |Rows |Bytes |Cost|Pstart|Pstop|TQ |IN-OUT|PQ Distrib|
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 445 | 17800 | 5 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) |:TQ10001| 445 | 17800 | 5 | | | Q1,01 | P->| QC (RAND)|
|*3 | HASH JOIN | | 445 | 17800 | 5 | | | Q1,01 | PCWP | |
| 4 | PX PARTITION RANGE ALL | | 107 | 1070 | 3 | 1 | 5 | Q1,01 | PCWC | |
| 5 | PX PARTITION HASH ALL | | 107 | 1070 | 3 | 1 | 3 | Q1,01 | PCWC | |
| 6 | TABLE ACCESS FULL |EMP_COMP| 107 | 1070 | 3 | 1 | 15| Q1,01 | PCWP | |
| 7 | PX RECEIVE | | 21 | 630 | 1 | | | Q1,01 | PCWP | |
| 8 | PX SEND PARTITION (KEY)|:TQ10000| 21 | 630 | 1 | | | Q1,00 | P->|PART (KEY)|
| 9 | PX BLOCK ITERATOR | | 21 | 630 | 1 | | | Q1,00 | PCWC | |
|10 | TABLE ACCESS FULL |DEPT2 | 21 | 630 | 1 | | | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------
 
이 계획은 옵티마이 저가 두 개의 컬럼 중 하나에서 부분 파티션 - 조인을 선택 함을 보여줍니다.
PX SEND 노드 유형은 PARTITION (KEY)이고 PQ Distrib 열은 PART (KEY) 또는 파티션 키 텍스트를 포함합니다.
이는 테이블 dept2가 EMP_COMP 및 결합의 스캔을 실행하는 병렬 실행 서버로 보내지는 department_id 조인 열을 
기반으로 재분할되었음을 의미합니다.
 
7.2.5.4 Example of Full Partition-Wise Join
다음 예에서 emp_comp 및 dept_hash는 해시 분할 열에서 조인되므로 전체 분할 방식의 조인을 사용할 수 있습니다.
PARTITION HASH 행 소스는 계획 테이블 출력의 조인 행 소스 위에 나타납니다.
 
CREATE TABLE dept_hash
PARTITION BY HASH(department_id)
PARTITIONS 3
PARALLEL 2
AS SELECT * FROM departments;
EXPLAIN PLAN FOR
SELECT /*+ PQ_DISTRIBUTE(e NONE NONE) ORDERED */ e.last_name,
d.department_name
FROM emp_comp e, dept_hash d
WHERE e.department_id = d.department_id;
------------------------------------------------------------------------------------------------
|Id| Operation | Name |Rows|Bytes|Cost|Pstart|Pstop|TQ |IN-OUT|PQ Distrib|
------------------------------------------------------------------------------------------------
| 0| SELECT STATEMENT | | 106 | 2544 | 8 | | | | | |
| 1| PX COORDINATOR | | | | | | | | | |
| 2| PX SEND QC (RANDOM) | :TQ10000 | 106 | 2544 | 8 | | | Q1,00 | P->|QC (RAND)|
| 3| PX PARTITION HASH ALL | | 106 | 2544 | 8 | 1 | 3 | Q1,00 | PCWC | |
|*4| HASH JOIN | | 106 | 2544 | 8 | | | Q1,00 | PCWP | |
| 5| PX PARTITION RANGE ALL| | 107 | 1070 | 3 | 1 | 5 | Q1,00 | PCWC | |
| 6| TABLE ACCESS FULL | EMP_COMP | 107 | 1070 | 3 | 1 | 15 | Q1,00 | PCWP | |
| 7| TABLE ACCESS FULL | DEPT_HASH | 27 | 378 | 4 | 1 | 3 | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------
PX PARTITION RANGE 행 소스가 emp_comp 스캔 동안 나타나는 동안 PX PARTITION HASH 행 소스가 
계획 테이블 출력의 조인 행 소스 맨 위에 나타납니다.
각 병렬 실행 서버는 emp_comp의 전체 해시 파티션과 dept_hash의 전체 파티션 조인을 수행합니다.
 
7.2.5.5 Examples of INLIST ITERATOR and EXPLAIN PLAN
INLIST ITERATOR 조작은 인덱스가 IN리스트 술어를 구현하는 경우 EXPLAIN PLAN 출력에 나타납니다. 
SELECT * FROM emp WHERE empno IN (787679007902);
EXPLAIN PLAN 출력은 다음과 같이 나타납니다.
 
OPERATION OPTIONS OBJECT_NAME
---------------- --------------- --------------
SELECT STATEMENT
INLIST ITERATOR
TABLE ACCESS BY ROWID EMP
INDEX RANGE SCAN EMP_EMPNO
 
INLIST ITERATOR 조작은 IN리스트 술어의 각 값에 대한 계획의 다음 조작을 반복합니다.
다음 절에서는 파티션 된 테이블과 인덱스에 대해 IN-list 열의 세 가지 유형을 설명합니다.
 
7.2.5.5.1 When the IN-List Column is an Index Column: Example
IN-list 열 empno가 인덱스 열이지만 partition 열이 아닌 경우 계획은 다음과 같습니다
(IN-list 연산자는 테이블 작업 전에 나타나지만 파티션 작업 이후에 나타납니다).
OPERATION OPTIONS OBJECT_NAME PARTIT_START PARTITION_STOP
---------------- ------------ ----------- ------------ --------------
SELECT STATEMENT
PARTITION RANGE ALL KEY(INLIST) KEY(INLIST)
INLIST ITERATOR
TABLE ACCESS BY LOCAL INDEX ROWID EMP KEY(INLIST) KEY(INLIST)
INDEX RANGE SCAN EMP_EMPNO KEY(INLIST) KEY(INLIST)
 
파티션 시작 및 중지 키에 대한 KEY (INLIST) 지정은 INlist 술어가 인덱스 시작 및 중지 키에 표시되도록 지정합니다.
 
7.2.5.5.2 When the IN-List Column is an Index and a Partition Column: Example
empno가 색인 된 열과 파티션 열인 경우 계획에는 파티션 작업 전에 INLIST ITERATOR 작업이 포함됩니다.
OPERATION OPTIONS OBJECT_NAME PARTITION_START PARTITION_STOP
---------------- ------------ ----------- --------------- --------------
SELECT STATEMENT
INLIST ITERATOR
PARTITION RANGE ITERATOR KEY(INLIST) KEY(INLIST)
TABLE ACCESS BY LOCAL INDEX ROWID EMP KEY(INLIST) KEY(INLIST)
INDEX RANGE SCAN EMP_EMPNO KEY(INLIST) KEY(INLIST)
 
7.2.5.5.3 When the IN-List Column is a Partition Column: Example
empno가 파티션 컬럼이고 인덱스가없는 경우 INLIST ITERATOR 조작이 할당되지 않습니다.
OPERATION OPTIONS OBJECT_NAME PARTITION_START PARTITION_STOP
---------------- ------------ ----------- --------------- --------------
SELECT STATEMENT
PARTITION RANGE INLIST KEY(INLIST) KEY(INLIST)
TABLE ACCESS FULL EMP KEY(INLIST) KEY(INLIST)
 
emp_empno가 비트 맵 색인 인 경우 계획은 다음과 같습니다.
OPERATION OPTIONS OBJECT_NAME
---------------- --------------- --------------
SELECT STATEMENT
INLIST ITERATOR
TABLE ACCESS BY INDEX ROWID EMP
BITMAP CONVERSION TO ROWIDS
BITMAP INDEX SINGLE VALUE EMP_EMPNO
 
7.2.5.6 Example of Domain Indexes and EXPLAIN PLAN
또한 EXPLAIN PLAN을 사용하여 도메인 인덱스에 대한 사용자 정의 CPU 및 I / O 비용을 얻을 수 있습니다.
EXPLAIN PLAN은 이러한 통계를 PLAN_TABLE의 OTHER 컬럼에 표시합니다.
예를 들어, 테이블 emp에 재개 열의 도메인 색인 emp_resume을 사용하는 사용자 정의 연산자 CONTAINS가 있고 색인 유형 emp_resume이 연산자 CONTAINS를 지원한다고 가정하십시오.
다음 쿼리에 대한 계획을 설명합니다.
SELECT * FROM emp WHERE CONTAINS(resume, 'Oracle'= 1
데이터베이스는 다음 계획을 표시 할 수 있습니다.
OPERATION OPTIONS OBJECT_NAME OTHER
----------------- ----------- ------------ ----------------
SELECT STATEMENT
TABLE ACCESS BY ROWID EMP
DOMAIN INDEX EMP_RESUME CPU: 300, I/O: 4
 
7.2.6 PLAN_TABLE Columns
EXPLAIN PLAN 문에 사용되는 PLAN_TABLE에는 이 주제에 나열된 컬럼이 들어 있습니다.
 
Table 7-1,2,3 PLAN_TABLE Columns
 
7.3 Execution Plan Reference
 
7.3.1 Execution Plan Views
다음 동적 성능 및 데이터 사전 뷰는 실행 계획에 대한 정보를 제공합니다.
 
Table 7-4 Execution Plan Views
V $ SQL_SHARED_CURSOR : 특정 하위 커서가 기존 하위 커서와 공유되지 않는 이유를 설명합니다.
각 열은 커서를 공유 할 수없는 구체적인 이유를 나타냅니다.
USE_FEEDBACK_STATS 열은 자식 커서가 재 최적화로 인해 일치하지 않는지 여부를 나타냅니다.
V $ SQL_PLAN : 모든 최종 계획에 나타나는 모든 행의 수퍼 세트를 포함합니다.
PLAN_LINE_ID에 연속적으로 번호가 매겨 지지만 단일 최종 계획의 경우 ID가 연속되지 않을 수 있습니다.
V $ SQL_PLAN_STATISTICS_ALL : SQL 메모리 (정렬 또는 해시 조인)를 사용하는 행 소스에 대한 메모리 사용 통계를 포함합니다.
이 뷰는 V $ SQL_PLAN의 정보를 V $ SQL_PLAN_STATISTICS 및 V $ SQL_WORKAREA의 실행 통계와 연결합니다.
 
7.3.2 PLAN_TABLE Columns
PLAN_TABLE은 EXPLAIN PLAN 문에서 사용됩니다.
PLAN_TABLE은 표 7-5에 나열된 열을 포함합니다.
 
Table 7-5 PLAN_TABLE Columns
 
Table 7-6 (Cont.) Values of DISTRIBUTION Column of the PLAN_TABLE
 
Table 7-7 (Cont.) OPERATION and OPTIONS Values Produced by EXPLAIN PLAN
 
7.3.3 DBMS_XPLAN Program Units
DBMS_XPLAN Program Units 주제는 적응 계획에 액세스하는데 관련된 DBMS_XPLAN 함수 및 매개 변수에 대한 참고 사항을 제공합니다.
 
Table 7-8 DBMS_XPLAN Functions and Parameters Relevant for Adaptive Queries
 
DISPLAY_PLAN : FORMAT 인수는 수식어 ADAPTIVE를 지원합니다.
ADAPTIVE를 지정하면 출력에는 기본 계획이 포함됩니다.
각 동적 부속 계획의 경우, 계획은 대체 될 수있는 원본의 행 소스와이를 대체 할 행 소스의 목록을 표시합니다.
format 인수가 개요 표시를 지정하면이 함수는 동적 하위 계획의 각 옵션에 대한 힌트를 표시합니다.
계획이 적응 형 쿼리 계획이 아닌 경우 함수는 기본 계획을 표시합니다.
ADAPTIVE를 지정하지 않으면 계획은있는 그대로 표시되지만 주 섹션에 동적 인 행 소스를 표시하는 추가 설명이 표시됩니다.
DISPLAY_CURSOR : FORMAT 인수는 수정 자 ADAPTIVE를 지원합니다.
ADAPTIVE를 지정하면 출력에는 다음이 포함됩니다.
• 최종 계획. 실행이 완료되지 않은 경우 출력에는 현재 계획이 표시됩니다. 또한이 섹션에는 계획에 영향을주는 런타임 최적화에 대한 참고 사항이 포함되어 있습니다.
• 권장 계획. 보고 모드에서 출력에는 실행 통계에 따라 선택되는 계획이 포함됩니다.
• 동적 계획. 결과는 최적화 프로그램이 선택한 기본 계획과 다른 계획 부분을 요약합니다.
• 재 최적화. 출력은 재 최적화로 인해 후속 실행시 선택 될 계획을 표시합니다.
cs