14.1. 윈 토토윈 토토

PostgreSQLa쿼리 계획각 쿼리마다 수신합니다. 쿼리 구조와 데이터의 속성에 맞는 올바른 계획을 선택하는 것은 좋은 성능에 절대적으로 중요하므로 시스템에는 복잡한 것이 포함됩니다플래너좋은 계획을 선택하려고합니다. 를 윈 토토할 수 있습니다.윈 토토명령은 플래너가 쿼리에 대해 어떤 쿼리 계획을 작성하는지 확인하십시오. 계획 읽기는 마스터하는 데 약간의 경험이 필요한 예술이지만이 섹션은 기본 사항을 다루려고 시도합니다.

이 섹션의 예는 a 후 회귀 테스트 데이터베이스에서 가져옵니다진공 분석, 9.3 개발 소스 사용. 예제를 직접 시도하면 비슷한 결과를 얻을 수 있어야하지만 예상 비용과 행 수는 약간 달라질 수 있습니다.분석의 통계는 정확한 것이 아닌 임의의 샘플이며 비용이 본질적으로 다소 플랫폼 의존적이기 때문에

예제 윈 토토윈 토토의 기본값텍스트출력 형식. 인간이 읽기에 편리하고 편리합니다. 피드를 원한다면윈 토토의 추가 분석을 위해 프로그램에 대한 출력은 기계로 읽을 수있는 출력 형식 (XML, JSON 또는 YAML) 중 하나를 대신 사용해야합니다.

14.1.1. 윈 토토기본

쿼리 계획의 구조는의 나무입니다.계획 노드. 트리의 하단 레벨의 노드는 스캔 노드입니다. 테이블에서 원시 행을 반환합니다. 다양한 테이블 액세스 방법에 대한 다양한 유형의 스캔 노드가 있습니다 : 순차적 스캔, 인덱스 스캔 및 비트 맵 인덱스 스캔. 와 같은 비 테이블 행 소스도 있습니다.조항 및 설정 함수From, 자체 스캔 노드 유형이 있습니다. 쿼리가 원시 행의 결합, 집계, 정렬 또는 기타 작업이 필요한 경우 스캔 노드 위에 추가 노드가있어 이러한 작업을 수행합니다. 다시 말하지만, 이러한 작업을 수행하는 가능한 방법은 하나 이상 있으므로 다른 노드 유형도 여기에 나타날 수 있습니다. 의 출력윈 토토플랜 트리의 각 노드마다 하나의 줄이있어 기본 노드 유형과 비용이 해당 계획 노드의 실행을 위해 만든 비용 추정치를 보여줍니다. 노드의 추가 특성을 보여주기 위해 노드의 요약 라인에서 들여 쓰기 된 추가 선이 나타날 수 있습니다. 첫 번째 줄 (최상위 노드의 요약 라인)에는 계획의 총 실행 비용이 추정됩니다. 플래너가 최소화하려는 것은이 숫자입니다.

여기에 사소한 예가 있습니다. 출력이 어떻게 보이는지 보여주기 위해 :

윈 토토 *에서 10에서 선택하십시오.

                         쿼리 계획
----------------------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..458.00 행 = 10000 너비 = 244)

이 쿼리가 없기 때문에여기서조항, 테이블의 모든 행을 스캔해야하므로 플래너는 간단한 순차적 스캔 계획을 사용하도록 선택했습니다. 괄호 안에 인용 된 숫자는 (왼쪽에서 오른쪽으로) :

  • 예상 시작 비용. 이것은 출력 단계가 시작되기 전에 소비 된 시간 (예 : 정렬 노드에서 정렬을 수행 할 시간입니다.

  • 총 비용. 이는 계획 노드가 완성 된 것으로 간주되며, 즉 사용 가능한 모든 행이 검색된다는 가정에 따라 언급됩니다. 실제로 노드의 상위 노드는 사용 가능한 모든 행을 읽지 않는 것이 멈출 수 있습니다 (참조Limit아래 예).

  • 이 계획 노드에 의한 추정 행 출력 수. 다시, 노드는 완료로 실행되는 것으로 가정합니다.

  • 이 계획 노드 (바이트)에 의해 출력의 평균 평균 폭

비용은 플래너의 비용 매개 변수에 의해 결정된 임의 단위로 측정됩니다 (참조섹션 19.7.2). 전통적인 관행은 디스크 페이지 가져 오기 단위의 비용을 측정하는 것입니다. 즉,seq_page_cost전통적으로 설정되었습니다1.0그리고 다른 비용 매개 변수는 이에 비해 설정됩니다. 이 섹션의 예제는 기본 비용 매개 변수로 실행됩니다.

상위 노드의 비용에는 모든 하위 노드의 비용이 포함되어 있음을 이해하는 것이 중요합니다. 비용은 플래너가 관심을 갖는 것만 반영한다는 것을 인식하는 것도 중요합니다. 특히, 비용은 결과 행을 클라이언트에게 전송하는 데 소요되는 시간을 고려하지 않으며, 이는 실제 경과 시간에서 중요한 요소가 될 수 있습니다. 그러나 플래너는 계획을 변경하여 변경할 수 없기 때문에이를 무시합니다. (모든 정확한 계획은 동일한 행 세트를 출력합니다. 우리는 신뢰합니다.)

the값은 계획 노드에 의해 처리되거나 스캔 된 행의 수가 아니라 노드에서 방출 된 숫자이기 때문에 약간 까다 롭습니다. 이것은 종종 스캔 한 숫자보다 적습니다.여기서-노드에 적용되는 클레스트 조건. 이상적으로 최상위 행 추정치는 쿼리에 의해 실제로 반환, 업데이트 또는 삭제 된 행의 수에 근사합니다.

예제로 돌아 가기 :

10에서 선택 *에서 *에서 *;

                         쿼리 계획
----------------------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..458.00 행 = 10000 너비 = 244)

이 숫자는 매우 간단하게 파생됩니다. 그렇다면 :

relname = 'tenk1'; pg_class에서 reelpages, reltuples를 선택합니다.

당신은 그것을 알게 될 것입니다Tenk1358 개의 디스크 페이지와 10000 행이 있습니다. 예상 비용은 (디스크 페이지 읽기 *로 계산됩니다.seq_page_cost) + (줄 스캔 *CPU_TUPLE_COST). 기본적으로seq_page_costis 1.0 andCPU_TUPLE_COST는 0.01이므로 추정 비용은 (358 * 1.0) + (10000 * 0.01) = 458입니다.

이제 쿼리를 수정하겠습니다여기서조건 :

10 <7000에서 tenk1에서 선택 *을 선택하십시오.

                         쿼리 계획
-------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..483.00 행 = 7001 너비 = 244)
   필터 : (고유 한 <7000)

윈 토토출력 표시여기서절로 적용되는 조항필터SEQ 스캔 계획 노드에 첨부 된 조건. 이는 계획 노드가 스캔 한 각 행의 조건을 확인하고 조건을 전달하는 것만 출력 함을 의미합니다. 출력 행의 추정치는 때문에 감소했습니다.여기서절. 그러나 스캔은 여전히 ​​10000 행을 모두 방문해야하므로 비용이 줄어들지 않았습니다. 사실 그것은 조금 올라갔습니다 (10000 *cpu_operator_cost, 정확하게) 추가 CPU 시간을 반영하여여기서조건.

이 쿼리를 선택할 실제 행 수는 7000이지만추정치는 대략적인 것입니다. 이 실험을 복제하려고하면 약간 다른 추정치가 나타날 것입니다. 또한 각각 변경 될 수 있습니다분석명령, 통계가 생성 되었기 때문에Analyze테이블의 무작위 샘플에서 가져 왔습니다.

이제 조건을보다 제한적으로 만들자 :

10 <100에서 tenk1에서 선택 *을 선택하십시오.

                                  쿼리 계획
-------------------------------------------------------------------------------------
 Tenk1의 비트 맵 힙 스캔 (비용 = 5.07..229.20 줄 = 101 너비 = 244)
   COND를 다시 확인하십시오 : (고유 1 <100)
   - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0)
         색인 조건 : (고유 1 <100)

여기서 플래너는 2 단계 계획을 사용하기로 결정했습니다. 아동 계획 노드는 색인을 방문하여 인덱스 조건과 일치하는 행의 위치를 ​​찾은 다음 상단 계획 노드는 실제로 테이블 자체에서 해당 행을 가져옵니다. 별도의 행을 따로 가져 오는 것은 순차적으로 읽는 것보다 훨씬 비싸지 만 테이블의 모든 페이지를 방문 할 필요는 없기 때문에 여전히 순차적 스캔보다 저렴합니다. (두 개의 계획 수준을 사용하는 이유는 상단 계획 노드가 독해하기 전에 인덱스로 식별 된 행 위치를 물리적 순서로 정렬하여 별도의 페치 비용을 최소화하기 때문입니다.BitMap노드 이름에 언급 된 것은 정렬을 수행하는 메커니즘입니다.)

이제 다른 조건을 추가하자여기서절 :

윈 토토 *에서 10 <100 및 stringu1 = 'xxx';

                                  쿼리 계획
-------------------------------------------------------------------------------------
 Tenk1의 비트 맵 힙 스캔 (비용 = 5.04..229.43 줄 = 1 너비 = 244)
   COND를 다시 확인하십시오 : (고유 1 <100)
   필터 : (stringu1 = 'xxx':: name)
   - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0)
         색인 조건 : (고유 1 <100)

추가 조건StringU1 = 'xxx'출력 행 카운트 추정치를 줄이지 만 여전히 동일한 행 세트를 방문해야하기 때문에 비용은 아닙니다.StringU1조항은 색인 조건으로 적용 할 수 없습니다.이 인덱스는에만 있으므로고유 1열. 대신 인덱스에 의해 검색된 행의 필터로 적용됩니다. 따라서 비용은 실제로이 추가 점검을 반영하기 위해 약간 증가했습니다.

경우에 따라 플래너가 a 선호합니다.단순색인 스캔 계획 :

윈 토토을 선택하십시오 * tenk1에서 ureight1 = 42;

                                 쿼리 계획
----------------------------------------------------------------------------------
 Tenk1에서 Tenk1_unique1을 사용한 인덱스 스캔 (비용 = 0.29..8.30 행 = 1 너비 = 244)
   색인 조건 : (고유 1 = 42)

이 유형의 계획에서 테이블 행은 색인 순서대로 가져 오므로 읽는 데 더 비싸지 만 행 위치를 분류하는 데 드는 추가 비용은 그만한 가치가 없습니다. 단일 행만 가져 오는 쿼리에 대한이 계획 유형을 가장 자주 볼 수 있습니다. 또한 종종에 윈 토토됩니다.주문인덱스 순서와 일치하는 조건은 추가 분류 단계가 필요하지 않기 때문에주문 by. 이 예에서는 추가Order by Oright1인덱스가 이미 요청 된 주문을 제공하기 때문에 동일한 계획을 사용합니다.

플래너는 an을 구현할 수 있습니다.주문 by여러 가지 방법으로 조항. 위의 예는 그러한 순서 조항이 암시 적으로 구현 될 수 있음을 보여준다. 플래너는 또한 명백한 것을 추가 할 수 있습니다sort단계 :

Select * from Tenk1 Order에 의해 select *;
                            쿼리 계획
--------------------------------------------------------------------------------
 정렬 (비용 = 1109.39..1134.39 행 = 10000 너비 = 244)
   정렬 키 : 고유 한
   - tenk1에서 seq 스캔 (비용 = 0.00..445.00 행 = 10000 너비 = 244)

계획의 일부가 필요한 정렬 키의 접두사에 대한 주문을 보장하면 플래너는 대신 A를 사용하기로 결정할 수 있습니다.증분 정렬단계 :

윈 토토 *에서 * Tenk1 Order에서 4, 10 한계 100을 선택하십시오.
                                              쿼리 계획
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 한계 (비용 = 521.06..538.05 행 = 100 너비 = 244)
   - 증분 정렬 (비용 = 521.06..2220.95 행 = 10000 너비 = 244)
         정렬 키 : Four, Ten
         분리 된 키 : 4
         - tenk1에서 index_tenk1_on_four를 사용한 색인 스캔 (비용 = 0.29..1510.08 행 = 10000 너비 = 244)

일반 정렬과 비교하여 전체 결과 세트가 정렬되기 전에 튜플을 점차적으로 정렬 할 수 있으므로 특히를 최적화 할 수 있습니다.Limit쿼리. 또한 메모리 윈 토토량과 디스크에 정렬을 유출 할 가능성을 줄일 수 있지만 결과를 여러 정렬 배치로 분할하는 데 드는 오버 헤드가 증가하는 비용이 발생합니다..

참조 된 여러 열에 별도의 인덱스가있는 경우여기서, 플래너는 인덱스의 및 또는 또는 또는 조합을 사용하도록 선택할 수 있습니다 :

10 <100 및 고유 2 9000에서 10에서 선택 *을 선택하십시오.

                                     쿼리 계획
---------------------------------------------------------------------------------------------
 Tenk1의 비트 맵 힙 스캔 (비용 = 25.08..60.21 행 = 10 너비 = 244)
   COND를 다시 확인하십시오 : ((고유 1 <100) 및 (고유 2 9000))
   - bitmapand (비용 = 25.08..25.08 행 = 10 너비 = 0)
         - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0)
               색인 조건 : (고유 1 <100)
         - tenk1_unique2의 비트 맵 인덱스 스캔 (비용 = 0.00..19.78 행 = 999 너비 = 0)
               색인 조건 : (고유 2 9000)

그러나 이것은 두 인덱스를 모두 방문해야하므로 하나의 색인 만 사용하고 다른 조건을 필터로 처리하는 것과 비교할 때 반드시 승리는 아닙니다. 당신이 관련된 범위를 변화 시키면 그에 따라 계획이 변경 될 것입니다.

다음은의 효과를 보여주는 예입니다.Limit:

10 <100 및 고유 2 9000 리미트 2에서 10에서 선택 *을 선택하십시오.

                                     쿼리 계획
---------------------------------------------------------------------------------------------
 한계 (비용 = 0.29..14.48 줄 = 2 너비 = 244)
   - tenk1에서 tenk1_unique2를 사용한 색인 스캔 (비용 = 0.29..71.27 행 = 10 너비 = 244)
         색인 조건 : (고유 2 9000)
         필터 : (고유 한 <100)

이것은 위와 동일한 쿼리이지만 A를 추가했습니다.Limit모든 행을 검색 할 필요는 없으며 플래너가해야 할 일에 대한 마음이 바뀌 었습니다. 인덱스 스캔 노드의 총 비용과 행 카운트는 마치 완료된 것처럼 표시됩니다. 그러나 해당 행의 5 분의 1 만 검색 한 후 한도 노드가 중지 될 것으로 예상되므로 총 비용은 5 분의 1에 불과하며 실제 추정 비용입니다. 이 계획은 한계가 비트 맵 스캔의 시작 비용을 지불하는 것을 피할 수 없기 때문에 이전 계획에 한계 노드를 추가하는 것보다 선호됩니다. 따라서 총 비용은 해당 접근법의 25 개 이상의 유닛이 될 것입니다..

우리가 논의한 열을 윈 토토하여 두 개의 테이블을 결합 해 보자.

선택 선택 *
TENK1 T1, TENK2 T2로부터
여기서 t1.unique1 <10 및 t1.unique2 = t2.unique2;

                                      쿼리 계획
------------------------------------------------------------------------------------------------------
 중첩 루프 (비용 = 4.65..118.62 행 = 10 너비 = 488)
   - tenk1 t1의 비트 맵 힙 스캔 (비용 = 4.36..39.47 행 = 10 너비 = 244)
         COND를 다시 확인하십시오 : (고유 1 <10)
         - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..4.36 행 = 10 너비 = 0)
               색인 조건 : (고유 1 <10)
   - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (비용 = 0.29..7.91 행 = 1 너비 = 244)
         색인 조건 : (고유 2 = t1.unique2)

이 계획에는 입력 또는 어린이로 두 개의 테이블 스캔이있는 중첩 루프 조인 노드가 있습니다. 노드 요약 라인의 압입은 계획 트리 구조를 반영합니다. 가입은 첫 번째, 또는외부, 자식은 이전에 본 것과 비슷한 비트 맵 스캔입니다. 비용과 행 수는 우리가 얻은 것과 동일합니다SELECT ... WHEREINED 1 <10우리가 적용하고 있기 때문에어디고유 한 <10해당 노드에서. 그만큼t1.unique2 = t2.unique2절은 아직 관련이 없으므로 외부 스캔의 행 수에 영향을 미치지 않습니다. 중첩 루프 조인 노드가 두 번째로 실행됩니다.내부외부 어린이로부터 얻은 각 행에 대해 한 번 자식. 현재 외부 행의 열 값은 내부 스캔에 연결할 수 있습니다. 여기,t1.unique2외부 행의 값을 사용할 수 있으므로, 우리는 단순한 것으로 위에서 본 것과 유사한 계획과 비용을 얻습니다선택 ... 여기서 t2.unique2 =Constant케이스. (추정 비용은 실제로 위에서 보았던 것보다 약간 낮습니다. 반복 된 인덱스 스캔에서 발생할 것으로 예상되는 캐싱의 결과T2.) 루프 노드의 비용은 외부 스캔 비용과 각 외부 행에 대한 내부 스캔의 반복 (10 * 7.91, 여기)과 조인 처리를위한 약간의 CPU 시간을 기준으로 설정됩니다..

이 예에서 조인 출력 행 카운트는 두 스캔 행 카운트의 제품과 동일하지만 추가가있을 수 있기 때문에 모든 경우에 해당되는 것은 아닙니다여기서두 테이블을 언급하는 클로스는 입력 스캔이 아닌 결합 지점에서만 적용 할 수 있습니다. 예는 다음과 같습니다.

선택 사항 *
TENK1 T1, TENK2 T2로부터
여기서 t1.unique1 <10 및 t2.unique2 <10 및 t1.hundred <t2.hundred;

                                         쿼리 계획
-------------------------------------------------------------------------------------------------------
 중첩 루프 (비용 = 4.65..49.46 줄 = 33 너비 = 488)
   가입 필터 : (T1. Hundred <t2.hundred)
   - tenk1 t1의 비트 맵 힙 스캔 (비용 = 4.36..39.47 행 = 10 너비 = 244)
         COND를 다시 확인하십시오 : (고유 1 <10)
         - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..4.36 행 = 10 너비 = 0)
               색인 조건 : (고유 1 <10)
   - 구체화 (비용 = 0.29..8.51 행 = 10 너비 = 244)
         - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (비용 = 0.29..8.46 행 = 10 너비 = 244)
               색인 조건 : (고유 2 <10)

조건T1.Hundred <t2.hundred테스트 할 수 없습니다Tenk2_unique2index이므로 결합 노드에 적용됩니다. 이렇게하면 결합 노드의 추정 출력 행 카운트가 줄어들지 만 입력 스캔 중 하나는 변경되지 않습니다.

여기서 플래너가 선택한 것을 주목하십시오구체화구체화 된 계획 노드를 꼭대기에 넣음으로써 조인의 내부 관계. 이것은를 의미합니다.T2Nested-Loop Join Node가 외부 관계에서 각 행에 대해 한 번 해당 데이터를 10 번 읽어야하더라도 인덱스 스캔이 한 번만 수행됩니다. 구체화 노드는 읽기에 따라 메모리에 데이터를 저장 한 다음 각 후속 패스에서 메모리에서 데이터를 반환합니다..

OUTER 조인을 처리 할 때는 두 가지 모두가있는 계획 노드가 표시 될 수 있습니다.결합 필터및 평범한필터첨부 된 조건. 결합 필터 조건은 OUTER JOIN의에서 나옵니다.on조항, 따라서 결합 필터 조건에 실패하는 행은 여전히 ​​널 확장 행로 방출 될 수 있습니다. 그러나 일반 필터 조건은 외부 결합 규칙에 따라 적용되므로 무조건 행을 제거하기 위해 작용합니다. 내부 결합에는 이러한 유형의 필터간에 의미 적 차이가 없습니다.

Query의 선택성을 약간 변경하면 매우 다른 조인 계획을 얻을 수 있습니다.

선택 사항 *
TENK1 T1, TENK2 T2로부터
여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2;

                                        쿼리 계획
--------------------------------------------------------------------------------------------------
 해시 조인 (비용 = 230.47..713.98 행 = 101 너비 = 488)
   해시 조건 : (T2.Unique2 = t1.unique2)
   - TENK2 T2의 SEQ 스캔 (비용 = 0.00..445.00 행 = 10000 너비 = 244)
   - 해시 (비용 = 229.20..229.20 줄 = 101 너비 = 244)
         - tenk1 t1의 비트 맵 힙 스캔 (비용 = 5.07..229.20 줄 = 101 너비 = 244)
               COND를 다시 확인하십시오 : (고유 1 <100)
               - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0)
                     색인 조건 : (고유 1 <100)

여기서, 플래너는 해시 조인을 사용하기로 선택했으며,이 테이블의 행은 메모리 내 해시 테이블에 입력되고 다른 테이블이 스캔되고 해시 테이블이 각 행과 일치하도록 프로브됩니다. 다시 들여 쓰기가 계획 구조를 어떻게 반영하는지 다시 주목하십시오. 비트 맵 스캔Tenk1해시 테이블을 구성하는 해시 노드에 대한 입력입니다. 그런 다음 해시 결합 노드로 돌아와서 외부 아동 계획에서 행을 읽고 각각의 해시 테이블을 검색합니다..

다른 가능한 유형의 조인 유형은 여기에 윈 토토 된 병합 조인입니다.

선택 선택 *
TENK1 T1, ONEK T2로부터
여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2;

                                        쿼리 계획
--------------------------------------------------------------------------------------------------
 합병 조인 (비용 = 198.11..268.19 행 = 10 너비 = 488)
   병합 Cond : (T1.unique2 = T2.Unique2)
   - tenk1 t1에서 tenk1_unique2를 사용한 인덱스 스캔 (비용 = 0.29..656.28 행 = 101 너비 = 244)
         필터 : (고유 한 <100)
   - 정렬 (비용 = 197.83..200.33 행 = 1000 너비 = 244)
         정렬 키 : T2.Unique2
         - Onek t2의 SEQ 스캔 (비용 = 0.00..148.00 행 = 1000 너비 = 244)

합병 결합은 결합 키에 입력 데이터를 정렬해야합니다. 이 계획에서Tenk1데이터는 인덱스 스캔을 윈 토토하여 올바른 순서로 행을 방문하여 정렬되지만 순차적 스캔과 정렬이 선호됩니다.ONEK, 해당 테이블에 더 많은 행이 방문 할 것이 많기 때문입니다. (인덱스 스캔에 필요한 비 순차 디스크 액세스로 인해 많은 행을 정렬하기위한 인덱스 스캔을 종종 순차적으로 스캔합니다.)

변형 계획을 보는 한 가지 방법은 플래너가 가장 저렴하다고 생각한 전략을 무시하고섹션 19.7.1. (이것은 조잡한 도구이지만 유용합니다. 참조PostgreSQL : 문서 : 13 : 14.3. 명백한 스포츠 토토 베트맨 조항으로 플래너 제어.) 예를 들어, 순차적 스캔과 스토어가 테이블을 다루는 가장 좋은 방법이라고 확신하지 못한 경우ONEK이전 예에서는 시도 할 수 있습니다

set enable_sort = off;

선택 * *
TENK1 T1, ONEK T2로부터
여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2;

                                        쿼리 계획
--------------------------------------------------------------------------------------------------
 합병 조인 (비용 = 0.56..292.65 행 = 10 너비 = 488)
   병합 Cond : (T1.unique2 = T2.Unique2)
   - tenk1 t1에서 tenk1_unique2를 사용한 인덱스 스캔 (비용 = 0.29..656.28 행 = 101 너비 = 244)
         필터 : (고유 한 <100)
   - Onek t2에서 Onek_unique2를 사용한 색인 스캔 (비용 = 0.28..224.79 행 = 1000 너비 = 244)

플래너가 정렬을 생각한다는 것을 보여줍니다ONEKBy Index-Scanning은 순차적 인 스캔 및 소트보다 약 12% 더 비쌉니다. 물론 다음 질문은 그것이 옳은지 여부입니다. 우리는 그것을 윈 토토하는 것을 조사 할 수 있습니다분석, 아래에서 논의 된대로.

14.1.2. 분석 윈 토토

사용하여 플래너 추정치의 정확도를 확인할 수 있습니다윈 토토's분석옵션. 이 옵션으로윈 토토실제로 쿼리를 실행 한 다음 각 계획 노드 내에 축적 된 실제 행 카운트와 실제 실행 시간을 표시하고 평범한 것과 동일한 추정치윈 토토쇼. 예를 들어, 우리는 다음과 같은 결과를 얻을 수 있습니다.

분석 선택 *
TENK1 T1, TENK2 T2로부터
여기서 t1.unique1 <10 및 t1.unique2 = t2.unique2;

                                                           쿼리 계획
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 중첩 루프 (비용 = 4.65..118.62 행 = 10 너비 = 488) (실제 시간 = 0.128..0.377 행 = 10 루프 = 1)
   - tenk1 t1의 비트 맵 힙 스캔 (비용 = 4.36..39.47 행 = 10 너비 = 244) (실제 시간 = 0.057..0.121 행 = 10 루프 = 1)
         COND를 다시 확인하십시오 : (고유 1 <10)
         - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..4.36 행 = 10 너비 = 0) (실제 시간 = 0.024..0.024 행 = 10 루프 = 1)
               색인 조건 : (고유 1 <10)
   - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (비용 = 0.29..7.91 행 = 1 너비 = 244) (실제 시간 = 0.021..0.022 행 = 1 루프 = 10)
         색인 조건 : (고유 2 = t1.unique2)
 계획 시간 : 0.181 ms
 실행 시간 : 0.501 ms

실제 시간값은 실시간 밀리 초에 있지만비용추정치는 임의 단위로 표현됩니다. 그래서 그들은 일치하지 않을 것입니다. 일반적으로 가장 중요한 것은 추정 행 카운트가 현실에 상당히 가까운 지 여부입니다. 이 예에서 추정치는 모두 죽었지 만 실제로는 매우 드문 일입니다.

일부 쿼리 계획에서는 하위 플랜 노드를 두 번 이상 실행할 수 있습니다. 예를 들어, 내부 색인 스캔은 위의 중첩 루프 계획에서 외부 행당 한 번 실행됩니다. 그러한 경우루프값은 노드의 총 실행 수를보고하며 표시된 실제 시간 및 행 값은 평균 자격입니다. 이것은 비용 추정치가 표시되는 방식과 비교할 수 있도록하기 위해 수행됩니다. 곱하기루프실제로 노드에서 소비 된 총 시간을 얻는 값. 위의 예에서는 Index Scans On을 실행하는 데 총 0.220 밀리 초를 소비했습니다.Tenk2.

경우에 따라분석계획 노드 실행 시간 및 행 계산 이상의 추가 실행 통계를 보여줍니다. 예를 들어 정렬 및 해시 노드는 추가 정보를 제공합니다.

선택을 윈 토토하십시오 *
TENK1 T1, TENK2 T2로부터
여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2 t1.fiveThous의 순서;

                                                                 쿼리 계획
-------------------------------------------------------------------​-------------------------------------------------------------------​------
 정렬 (비용 = 717.34..717.59 행 = 101 너비 = 488) (실제 시간 = 7.761..7.774 줄 = 100 루프 = 1)
   정렬 키 : T1. 피브 러스
   정렬 방법 : QuickSort 메모리 : 77KB
   - 해시 조인
         해시 조건 : (T2.Unique2 = t1.unique2)
         - TENK2 T2의 SEQ 스캔 (비용 = 0.00..445.00 행 = 10000 너비 = 244) (실제 시간 = 0.007..2.583 행 = 10000 루프 = 1)
         - 해시 (비용 = 229.20..229.20 줄 = 101 너비 = 244) (실제 시간 = 0.659..0.659 행 = 100 루프 = 1)
               버킷 : 1024 배치 : 1 메모리 사용량 : 28KB
               - tenk1 t1의 비트 맵 힙 스캔 (비용 = 5.07..229.20 줄 = 101 너비 = 244) (실제 시간 = 0.080..0.526 행 = 100 루프 = 1)
                     COND를 다시 확인하십시오 : (고유 1 <100)
                     - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0) (실제 시간 = 0.049..0.049 행 = 100 루프 = 1)
                           색인 조건 : (고유 1 <100)
 계획 시간 : 0.194ms
 실행 시간 : 8.008 ms

정렬 노드는 윈 토토 된 정렬 메소드 (특히 정렬이 메모리 내 또는 온 디스크인지) 및 필요한 메모리 또는 디스크 공간의 양을 보여줍니다. 해시 노드는 해시 버킷과 배치의 수와 해시 테이블에 윈 토토되는 피크 양의 메모리를 보여줍니다. (배치 수가 하나를 초과하면 디스크 공간 윈 토토이 포함되지만 표시되지 않습니다.)

다른 유형의 추가 정보는 필터 조건에 의해 제거 된 행의 수입니다 :

10 <7에서 10 <7;

                                               쿼리 계획
---------------------------------------------------------------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..483.00 행 = 7000 너비 = 244) (실제 시간 = 0.016..5.107 행 = 7000 루프 = 1)
   필터 : (10 <7)
   필터로 제거 된 행 : 3000
 계획 시간 : 0.083 ms
 실행 시간 : 5.905ms

이 카운트는 조인 노드에 적용되는 필터 조건에 특히 유용 할 수 있습니다. 그만큼줄이 제거되었습니다라인은 결합 노드의 경우 적어도 하나의 스캔 한 행 또는 전위 조인 쌍이 필터 조건에 의해 거부 될 때만 나타납니다..

필터 조건과 유사한 경우Lossy인덱스 스캔. 예를 들어, 특정 요점을 포함하는 다각형에 대한이 검색을 고려하십시오.

polygon_tbl에서 선택 * 선택 * f1 @ 다각형 '(0.5,2.0)';

                                              쿼리 계획
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 polygon_tbl에서의 seq 스캔 (cost = 0.00..1.05 줄 = 1 너비 = 32) (실제 시간 = 0.044..0.044 행 = 0 루프 = 1)
   필터 : (f1 @ '((0.5,2))':: 다각형)
   필터에 의해 제거 된 행 : 4
 계획 시간 : 0.040ms
 실행 시간 : 0.083 MS

플래너는이 샘플 테이블이 인덱스 스캔으로 귀찮게하기에는 너무 작다 고 생각합니다. 따라서 필터 조건에 의해 모든 행이 거부되는 일반적인 순차적 스캔이 있습니다. 그러나 인덱스 스캔을 사용하도록 강요하면 다음을 볼 수 있습니다.

enable_seqscan을 OFF로 설정합니다.

polygon_tbl에서 선택 * 선택 *을 윈 토토하십시오. 여기서 f1 @ 다각형 '(0.5,2.0)';

                                                        쿼리 계획
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 polygon_tbl에서 gpolygonind를 사용한 인덱스 스캔 (비용 = 0.13..8.15 행 = 1 너비 = 32) (실제 시간 = 0.062..0.062 행 = 0 루프 = 1)
   색인 조건 : (f1 @ '((0.5,2))':: 다각형)
   인덱스 재확인으로 제거 된 행 : 1
 계획 시간 : 0.034ms
 실행 시간 : 0.144 ms

여기서 인덱스가 하나의 후보 행을 반환 한 다음 인덱스 조건의 재확인으로 거부되었음을 알 수 있습니다. 이것은 GIST 지수가이기 때문에 발생합니다.Lossy다각형 격리 테스트의 경우 : 실제로 대상과 겹치는 다각형으로 행을 반환 한 다음 해당 행에 대한 정확한 격리 테스트를 수행해야합니다..

윈 토토a버퍼분석더 많은 실행 시간 통계를 얻으려면 :

윈 토토 (분석, 버퍼) * 선택 * 10 <100 및 고유 2 9000;

                                                           쿼리 계획
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 Tenk1의 비트 맵 힙 스캔 (비용 = 25.08..60.21 행 = 10 너비 = 244) (실제 시간 = 0.323..0.342 행 = 10 루프 = 1)
   COND를 다시 확인하십시오 : ((고유 1 <100) 및 (고유 2 9000))
   버퍼 : 공유 적중 = 15
   - bitmapand (비용 = 25.08..25.08 행 = 10 너비 = 0) (실제 시간 = 0.309..0.309 행 = 0 루프 = 1)
         버퍼 : 공유 적중 = 7
         - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0) (실제 시간 = 0.043..0.043 행 = 100 루프 = 1)
               색인 조건 : (고유 1 <100)
               버퍼 : 공유 적중 = 2
         - tenk1_unique2의 비트 맵 인덱스 스캔 (비용 = 0.00..19.78 행 = 999 너비 = 0) (실제 시간 = 0.227..0.227 행 = 999 루프 = 1)
               색인 조건 : (고유 2 9000)
               버퍼 : 공유 적중 = 5
 계획 시간 : 0.088ms
 실행 시간 : 0.423 MS

버퍼쿼리의 어떤 부분이 가장 I/O 집약적인지 식별하는 데 도움이됩니다.

이를 명심하십시오분석실제로 쿼리를 실행하면 쿼리가 출력 할 수있는 결과가 무엇이든해도 모든 부작용이 평소와 같이 발생합니다.윈 토토데이터. 테이블을 변경하지 않고 데이터 수정 쿼리를 분석하려면 다음과 같은 나중에 명령을 다시 굴릴 수 있습니다.

시작;

Analyze Update Tenk1 세트 백 = 백 + 1 여기서 고유 1 <100;

                                                           쿼리 계획
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 Tenk1에 대한 업데이트 (비용 = 5.07..229.46 행 = 101 너비 = 250) (실제 시간 = 14.628..14.628 행 = 0 루프 = 1)
   - tenk1의 비트 맵 힙 스캔 (비용 = 5.07..229.46 행 = 101 너비 = 250) (실제 시간 = 0.101..0.439 행 = 100 루프 = 1)
         COND를 다시 확인하십시오 : (고유 1 <100)
         - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..5.04 행 = 101 너비 = 0) (실제 시간 = 0.043..0.043 행 = 100 루프 = 1)
               색인 조건 : (고유 1 <100)
 계획 시간 : 0.079ms
 실행 시간 : 14.727ms

롤백;

이 예에서 볼 수 있듯이 쿼리가 AN 일 때삽입, 업데이트또는삭제명령, 테이블 변경을 적용하는 실제 작업은 최상위 삽입, 업데이트 또는 삭제 계획 노드로 수행됩니다. 이 노드 아래의 계획 노드는 이전 행을 찾거나 새 데이터를 계산하는 작업을 수행합니다. 따라서 우리는 이미 본 것과 동일한 종류의 비트 맵 테이블 스캔을 볼 수 있으며 출력은 업데이트 된 행을 저장하는 업데이트 노드로 공급됩니다. 데이터 수정 노드에 상당한 양의 실행 시간이 걸릴 수 있지만 (여기서, 시간의 사자 공유를 소비하고 있음) 플래너는 현재 해당 작업을 윈 토토하기 위해 비용 추정치에 아무것도 추가하지는 않습니다. 이 작업은 모든 올바른 쿼리 계획에 대해 동일하므로 계획 결정에 영향을 미치지 않기 때문입니다.

언제업데이트또는삭제명령은 상속 계층에 영향을 미치며 출력이 다음과 같이 보일 수 있습니다.

업데이트에 윈 토토 부모 세트 f2 = f2 + 1 여기서 f1 = 101;
                                    쿼리 계획
---------------------------------------------------------------------------------------
 부모에 대한 업데이트 (비용 = 0.00..24.53 행 = 4 너비 = 14)
   부모에 대한 업데이트
   Child1에 대한 업데이트
   child2에 대한 업데이트
   Child3에 대한 업데이트
   - 부모의 SEQ 스캔 (비용 = 0.00..0.00 행 = 1 너비 = 14)
         필터 : (F1 = 101)
   - child1에서 child1_f1_key를 사용한 색인 스캔 (비용 = 0.15..8.17 행 = 1 너비 = 14)
         색인 조건 : (F1 = 101)
   - child2에서 child2_f1_key를 사용한 색인 스캔 (비용 = 0.15..8.17 행 = 1 너비 = 14)
         색인 조건 : (F1 = 101)
   - child3에서 child3_f1_key를 사용한 색인 스캔 (비용 = 0.15..8.17 행 = 1 너비 = 14)
         색인 조건 : (F1 = 101)

이 예에서 업데이트 노드는 원래 언급 된 상위 테이블뿐만 아니라 3 개의 하위 테이블을 고려해야합니다. 따라서 테이블 당 하나의 입력 스캐닝 하위 플랜이 있습니다. 명확성을 위해, 업데이트 노드에 주석이 달라서 해당 하위 플랜과 동일한 순서로 업데이트 될 특정 대상 테이블을 표시합니다. (이 주석은 새로운 것입니다PostgreSQL9.5; 이전 버전에서 독자는 하위 계획을 검사하여 대상 테이블을 직관해야했습니다.)

the계획 시간표시분석구문 분석 쿼리에서 쿼리 계획을 생성하고 최적화하는 데 걸리는 시간입니다. 구문 분석 또는 재 작성은 포함되지 않습니다.

the실행 시간표시분석 윈 토토집행자 스타트 업 및 종료 시간과 해고 된 트리거를 실행할 시간이 포함되어 있지만 구문 분석, 재 작성 또는 계획 시간은 포함되지 않습니다. 실행하는 데 소요되는 시간관련 인서트, 업데이트 또는 삭제 노드의 시간에 트리거가 포함되어 있습니다. 하지만 실행하는 데 소요되는 시간이후트리거가 계산되지 않기 때문에이후전체 계획을 완료 한 후 트리거가 해고됩니다. 각 방아쇠에 소비 된 총 시간 (하나또는이후)도 별도로 표시됩니다. 지연된 제한 조건 트리거는 거래 종료까지 실행되지 않으므로 전혀 고려되지 않습니다.분석.

14.1.3. 경고

실행 시간이 측정하는 두 가지 중요한 방법이 있습니다분석동일한 쿼리의 일반 실행에서 벗어날 수 있습니다. 첫째, 출력 행이 클라이언트에게 전달되지 않으므로 네트워크 전송 비용 및 I/O 변환 비용은 포함되지 않습니다. 둘째,에 의해 추가 된 측정 오버 헤드분석특히 느린 기계에서 중요 할 수 있습니다gettimeofday ()운영 시스템 호출. 를 윈 토토할 수 있습니다.토토 PostgreSQL :시스템에서 타이밍 오버 헤드를 측정하는 도구.

윈 토토결과를 실제로 테스트하는 것과는 다른 상황에 외삽되지 않아야합니다. 예를 들어 장난감 크기의 테이블의 결과는 큰 테이블에 적용되는 것으로 가정 할 수 없습니다. 플래너의 비용 추정치는 선형이 아니므로 더 크거나 작은 테이블에 대한 다른 계획을 선택할 수 있습니다. 극단적 인 예는 하나의 디스크 페이지만을 차지하는 테이블에서 인덱스 사용 가능 여부에 관계없이 거의 항상 순차적 스캔 계획을 얻을 수 있다는 것입니다. 플래너는 어쨌든 테이블을 처리하기 위해 하나의 디스크 페이지를 읽을 것이라는 것을 알고 있으므로 추가 페이지 읽기를 소비하는 데 인덱스를 보는 데 가치가 없습니다. (우리는 이런 일이 일어나는 것을 보았습니다polygon_tbl위의 예.)

실제 및 예상 값이 잘 어울리지 않는 경우가 있지만 실제로 잘못된 것은 없습니다. 그러한 사례 중 하나는 계획 노드 실행이 a에 의해 짧게 중지 될 때 발생합니다.Limit또는 유사한 효과. 예를 들어,에서Limit이전에 윈 토토한 쿼리,

윈 토토을 윈 토토하십시오 * 선택 * 10 <100 및 고유 2 9000 한계 2;

                                                          쿼리 계획
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.
 한계 (비용 = 0.29..14.71 행 = 2 너비 = 244) (실제 시간 = 0.177...0.249 행 = 2 루프 = 1)
   - tenk1에서 tenk1_unique2를 사용한 색인 스캔 (비용 = 0.29..72.42 행 = 10 너비 = 244) (실제 시간 = 0.174..0.244 행 = 2 루프 = 1)
         색인 조건 : (고유 2 9000)
         필터 : (고유 한 <100)
         필터로 제거 된 행 : 287
 계획 시간 : 0.096ms
 실행 시간 : 0.336 MS

인덱스 스캔 노드의 예상 비용 및 행 카운트는 마치 완료된 것처럼 표시됩니다. 그러나 실제로 제한 노드는 2 개를 얻은 후 행 요청 중지를 중지 했으므로 실제 행 카운트는 2에 불과하고 런타임은 비용 추정치가 제안하는 것보다 적습니다. 이것은 추정 오류가 아니라 추정치와 실제 값이 표시되는 방식의 불일치 만 있습니다.

합병 결합에는 무질서한 사람들을 혼란스럽게 할 수있는 측정 아티팩트도 있습니다. 병합 조인은 다른 입력이 소진되면 하나의 입력 읽기를 중지하고 한 입력의 다음 키 값은 다른 입력의 마지막 키 값보다 큽니다. 이 경우 더 이상 일치 할 수 없으므로 나머지 첫 입력을 스캔 할 필요가 없습니다. 이로 인해 한 아이를 모두 읽지 않고에 언급 된 결과와 같은 결과가 있습니다.LIMIT. 또한 외부 (첫 번째) 자식에 중복 키 값이있는 행이 포함되어 있으면 내부 (두 번째) 자식이 백업되고 그 주요 값과 일치하는 행 부분에 대해 철회됩니다..분석마치 실제 추가 행인 것처럼 동일한 내부 행의 반복 배출을 계산합니다. 외부 복제물이 많으면 내부 하위 계획 노드에 대한보고 된 실제 행 카운트가 실제로 내부 관계에있는 행의 수보다 훨씬 클 수 있습니다..

비트 맵 및 비트 맵 노드는 구현 제한으로 인해 실제 행 계산이 항상 0으로보고됩니다.

정상,윈 토토플래너가 만든 모든 계획 노드를 표시합니다. 그러나 실행자가 계획 시간에 사용할 수 없었던 매개 변수 값을 기반으로 행을 생성 할 수 없기 때문에 특정 노드를 실행할 필요가 없다고 판단 할 수있는 경우가 있습니다. (현재 이것은 분할 된 테이블을 스캔하는 Append 또는 Mergeappend 노드의 자식 노드에 대해서만 발생할 수 있습니다.) 이런 일이 발생하면 해당 계획 노드는에서 생략됩니다.윈 토토출력 및 A하위 계획 제거 :n대신 주석이 나타납니다.

정정 제출

문서에 올바른 것이 없으면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 윈 토토이 필요합니다. 사용이 양식문서 문제를보고하려면