EXPLAIN

EXPLAIN 명령을 사용하여 쿼리에 대한 쿼리 실행 플랜 또는 분배를 표시할 수 있습니다. 실행 플랜은 쿼리에서 참조하는 테이블이 스캔되는 방법을 지정합니다(예: 단순 순차 스캔).

여러 테이블이 참조되는 경우, 실행 플랜은 각 입력 테이블에서 필수 튜플을 가져오는 데 사용된 조인 알고리즘을 지정합니다. 실행 플랜에는 쿼리 실행 비용, 즉 쿼리 실행에 필요한 시간(밀리초)의 추정치가 포함됩니다.
  • 첫 번째 튜플이 리턴될 수 있기 전의 시작 시간.
  • 모든 튜플을 리턴하기 위한 총 시간.
LIMIT절로 리턴되는 튜플 수를 제한하는 경우, 플래너는 실제로 가장 효율적인 플랜을 추정하기 위해 엔드포인트 비용 간에 보간합니다.

구문

EXPLAIN 명령의 구문은 다음과 같습니다.
EXPLAIN [VERBOSE] [DISTRIBUTION] [PLANTEXT|PLANGRAPH] <query>

입력

EXPLAIN 명령의 입력은 다음과 같습니다.
표 1. EXPLAIN 입력
입력 설명
상세 단지 요약이 아닌 플랜 트리의 전체 내부 표현을 표시하며, 플랜을 포스트마스터 로그 파일에 전송합니다. 이 옵션은 디버깅에 유용합니다.
<query> 실행 플랜이 표시되는 쿼리입니다.
분포 분배 플랜을 표시합니다. DISTRIBUTION 서브명령을 사용하는 경우, EXPLAIN 명령은 DISTRIBUTE ON()을 지정하지 않은 CTAS 명령의 SELECT문에서 플래너가 사용한 분배를 인쇄합니다.
PLANTEXT 플랜을 텍스트로 표시합니다.
PLANGRAPH 플랜을 HTML로 표시합니다.

출력

EXPLAIN 명령의 출력은 다음과 같습니다.
테이블 2. EXPLAIN 출력
출력 설명
NOTICE: query plan: plan 명시적 쿼리 플랜에 대한 메시지의 리드입니다.
NOTICE: result-set distribution 분배 쿼리에 대한 메시지의 리드입니다.
EXPLAIN 명시적 쿼리 플랜 또는 분배 쿼리의 끝을 표시하는 메시지입니다.

특권

이 명령은 특정 특권을 요구하지 않습니다.

사용량

샘플 사용법은 다음과 같습니다.
  • 하나의 int4 컬럼과 128개 행의 테이블에서 단순 쿼리에 대한 쿼리 플랜을 표시합니다.
    MYDB.SCH1(USER)=> EXPLAIN SELECT * FROM foo;
           NOTICE:  QUERY PLAN:
       Seq Scan on foo  (cost=0.00..2.28 rows=128 width=4)
       EXPLAIN
  • emp 및 grp 테이블 간의 조인에 대한 쿼리 플랜을 표시합니다.
    MYDB.SCH1(USER)=> EXPLAIN SELECT emp.* FROM emp,grp WHERE 
    emp.id=grp.grp_id; 
       NOTICE: QUERY PLAN: 
       Hash Join (cost=0.01..0.04 rows=10000 width=28)
    -> Seq Scan on emp (cost=0.00..0.01 rows=1000 width=28)
    -> Hash (cost=0.01..0.01 rows=1000 width=4)
    -> Seq Scan on grp (cost=0.00..0.01 rows=1000 width=4) 
       EXPLAIN
  • TPHC 쿼리 3에 대한 쿼리 플랜을 표시합니다.
    MYDB.SCH1(USER)=> EXPLAIN SELECT
           l_orderkey, 
           sum(l_extendedprice * (1 - l_discount)) as revenue, 
           o_orderdate, 
           o_shippriority 
       FROM    
           customer, 
           orders, 
           lineitem 
       WHERE 
           c_mktsegment = 'BUILDING' 
           and c_custkey = o_custkey 
           and l_orderkey = o_orderkey 
           and o_orderdate < date '1995-03-15' 
           and l_shipdate > date '1995-03-15'
       GROUP BY 
           l_orderkey, 
           o_orderdate, 
           o_shippriority 
       ORDER BY 
           revenue desc, 
           o_orderdate 
       LIMIT 10;
    NOTICE: QUERY PLAN:
    Limit (cost=315799480130.29..315799480130.29 rows=10 width=28)
    -> Sort (cost=315799480130.29..315799480130.29 rows=360899981912
    width=28)
         -> Aggregate (cost=19476.76..112854066.90 rows=360899981912
    width=28)
            -> Group (cost=19476.76..72822.55 rows=360899981912 width=28)
               -> Hash Join (cost=19476.76..43432.67 rows=31349208 width=28)
                  -> Seq Scan on lineitem (cost=0.00..17842.17 rows=322475815
    width=20)
               -> Hash (cost=19476.76..19476.76 rows=14582120 width=12)
                  -> Hash Join (cost=1347.66..19476.76 rows=14582120
    width=12)
                     -> Seq Scan on orders (cost=0.00..3606.62
    rows=72910603 width=16)
                     -> Hash (cost=550.60..550.60 rows=3000000 width=4)
                        -> Seq Scan on customer (cost=0.00..550.60
    rows=3000000 width=4)
    EXPLAIN
  • CTAS 명령에서 SELECT문의 분배를 표시합니다.
       dev(admin)=> EXPLAIN DISTRIBUTION SELECT COUNT(*),grp FROM emp 
    GROUP BY grp;
       NOTICE:  Result-set distribution (for "CREATE TABLE AS")
       Distributed on hash: "grp"
       EXPLAIN