이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
당신은 다음과 같은 페이지를 보고 싶을 수도 있습니다.PostgreSQL : 문서 : 17 : 14.1. 설명 토토 사이트 순위버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

14.1. 토토 커뮤니티설명

PostgreSQLa를 고안쿼리 계획수신하는 각 쿼리에 대해. 쿼리 구조와 데이터 속성을 일치시키는 올바른 계획을 선택하는 것은 좋은 성능을 위해 절대적으로 중요하므로 시스템에는 복잡한플래너좋은 계획을 선택하려고 노력합니다. 다음을 사용할 수 있습니다.설명플래너가 쿼리에 대해 어떤 쿼리 계획을 생성하는지 확인하는 명령입니다. 계획 읽기는 숙달하려면 약간의 경험이 필요한 기술이지만, 이 섹션에서는 기본 사항을 다루려고 합니다.

이 섹션의 예는 다음을 수행한 후 회귀 테스트 데이터베이스에서 추출되었습니다.진공 분석, 9.3 개발 소스 사용. 예제를 직접 시도해 보면 비슷한 결과를 얻을 수 있지만 예상 비용과 행 개수는 다음과 같은 이유로 약간 다를 수 있습니다.분석의 통계는 정확하지 않고 무작위 샘플이며 비용은 본질적으로 플랫폼에 따라 다소 다르기 때문입니다.

예제 토토 커뮤니티설명의 기본값텍스트사람이 읽기에 작고 편리한 출력 형식입니다. 먹이를 주고 싶다면설명11726_11860

14.1.1. 설명기본사항

쿼리 계획의 구조는 트리입니다.계획 노드. 트리의 맨 아래 수준에 있는 노드는 스캔 노드입니다. 즉, 테이블의 원시 행을 반환합니다. 다양한 테이블 액세스 방법에 대해 다양한 유형의 스캔 노드가 있습니다(순차 스캔, 인덱스 스캔, 비트맵 인덱스 스캔). 다음과 같은 테이블이 아닌 행 소스도 있습니다.절 및 집합 반환 함수발신은 고유한 스캔 노드 유형을 가지고 있습니다. 쿼리에 원시 행에 대한 조인, 집계, 정렬 또는 기타 작업이 필요한 경우 이러한 작업을 수행하기 위해 스캔 노드 위에 추가 노드가 있습니다. 다시 말하지만 일반적으로 이러한 작업을 수행하는 방법은 여러 가지가 있으므로 여기에도 다양한 노드 유형이 나타날 수 있습니다. 의 출력설명에는 계획 트리의 각 노드에 대해 한 줄이 있으며, 기본 노드 유형과 계획자가 해당 계획 노드 실행을 위해 작성한 예상 비용을 보여줍니다. 노드의 추가 속성을 표시하기 위해 노드의 요약 줄에서 들여쓰기된 추가 줄이 나타날 수 있습니다. 첫 번째 줄(최상위 노드에 대한 요약 줄)에는 계획에 대한 예상 총 실행 비용이 있습니다. 기획자가 최소화하려고 하는 것이 바로 이 숫자입니다.

다음은 출력이 어떻게 보이는지 보여주기 위한 간단한 예입니다.

설명 선택 * FROM tenk1;

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

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

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

  • 추정 총 비용. 이는 계획 노드가 완료될 때까지 실행된다는 가정, 즉 사용 가능한 모든 행이 검색된다는 가정에 따라 설명됩니다. 실제로 노드의 상위 노드는 사용 가능한 모든 행을 읽지 못하고 중지될 수 있습니다(제한아래 예).

  • 이 계획 노드에 의해 출력된 예상 행 수입니다. 다시 말하지만, 노드는 완료될 때까지 실행되는 것으로 가정됩니다.

  • 이 계획 노드에 의해 출력된 행의 예상 평균 너비(바이트).

비용은 계획자의 비용 매개변수에 따라 결정된 임의의 단위로 측정됩니다(참조섹션 19.7.2). 전통적인 방식은 디스크 페이지 가져오기 단위로 비용을 측정하는 것입니다. 즉,seq_page_cost일반적으로 다음과 같이 설정됩니다.1.0그리고 다른 비용 매개변수는 이에 맞춰 설정됩니다. 이 섹션의 예시는 기본 비용 매개변수를 토토 커뮤니티하여 실행됩니다.

상위 노드의 비용에는 모든 하위 노드의 비용이 포함된다는 점을 이해하는 것이 중요합니다. 비용에는 기획자가 관심을 두는 사항만 반영된다는 점을 인식하는 것도 중요합니다. 특히 비용에는 결과 행을 클라이언트에 전송하는 데 소요된 시간이 고려되지 않았는데, 이는 실제 경과 시간에 중요한 요소가 될 수 있습니다. 그러나 계획자는 계획을 변경하여 변경할 수 없기 때문에 이를 무시합니다. (모든 올바른 계획은 동일한 행 집합을 출력할 것이라고 믿습니다.)

값은 계획 노드에서 처리하거나 스캔한 행 수가 아니라 노드에서 내보낸 행 수이기 때문에 약간 까다롭습니다. 이는 필터링 결과로 스캔된 숫자보다 적은 경우가 많습니다.어디-노드에 적용되는 절 조건입니다. 이상적으로 최상위 행 추정치는 쿼리에 의해 실제로 반환, 업데이트 또는 삭제된 행 수와 비슷합니다.

예로 돌아가기:

설명 선택 * FROM tenk1;

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

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

pg_class WHERE relname = 'tenk1'에서 relpages, reltuples 선택;

당신은 그것을 발견할 것입니다tenk1에는 358개의 디스크 페이지와 10000개의 행이 있습니다. 예상 비용은 다음과 같이 계산됩니다(읽은 디스크 페이지 *seq_page_cost) + (스캔된 행 *cpu_tuple_cost). 기본적으로,seq_page_cost1.0이고cpu_tuple_cost은 0.01이므로 예상 비용은 (358 * 1.0) + (10000 * 0.01) = 458입니다.

이제 쿼리를 수정하여 다음을 추가하겠습니다.어디조건:

설명 선택 * FROM tenk1 WHERE 고유1 < 7000;

                         쿼리 계획
----------------------------------
 tenk1의 시퀀스 스캔(비용=0.00..483.00행=7001너비=244)
   필터: (고유1 < 7000)

다음에 주목하세요.설명출력에 다음이 표시됩니다.어디다음으로 적용되는 절필터조건이 Seq 스캔 계획 노드에 연결되었습니다. 이는 계획 노드가 스캔하는 각 행의 조건을 확인하고 조건을 통과하는 행만 출력한다는 의미입니다. 출력 행의 추정치는 다음으로 인해 감소되었습니다.어디절. 그러나 스캔은 여전히 ​​10000개 행을 모두 방문해야 하므로 비용은 줄어들지 않습니다. 실제로는 조금 올랐습니다(10000 *cpu_operator_cost, 정확하게는) 확인에 소요된 추가 CPU 시간을 반영합니다.어디조건.

이 쿼리가 선택하는 실제 행 수는 7000개이지만,추정치는 대략적인 수치일 뿐입니다. 이 실험을 복제하려고 하면 아마도 약간 다른 추정치를 얻게 될 것입니다. 또한 매번 변경될 수 있습니다.분석명령, 왜냐하면 통계는분석테이블의 무작위 샘플에서 가져옵니다.

이제 조건을 더욱 제한적으로 만들어 보겠습니다.

설명 선택 * FROM tenk1 WHERE 고유1 < 100;

                                  쿼리 계획
----------------------------------------------------
 tenk1의 비트맵 힙 스캔(비용=5.07..229.20행=101 너비=244)
   조건 재확인: (unique1 < 100)
   - tenk1_unique1의 비트맵 인덱스 스캔(비용=0.00..5.04행=101 너비=0)
         인덱스 조건: (unique1 < 100)

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

이제 다른 조건을 추가해 보겠습니다.어디절:

설명 선택 * FROM tenk1 WHERE Unique1 < 100 AND stri토토 커뮤니티u1 = 'xxx';

                                  쿼리 계획
----------------------------------------------------
 tenk1의 비트맵 힙 스캔(비용=5.04..229.43행=1너비=244)
   조건 재확인: (unique1 < 100)
   필터: (stri토토 커뮤니티u1 = 'xxx'::name)
   - tenk1_unique1의 비트맵 인덱스 스캔(비용=0.00..5.04행=101 너비=0)
         인덱스 조건: (unique1 < 100)

추가된 조건stri토토 커뮤니티u1 = 'xxx'은 출력 행 수 추정치를 줄이지만 여전히 동일한 행 집합을 방문해야 하기 때문에 비용은 줄지 않습니다. 주의할 점은stri토토 커뮤니티u1절은 색인 조건으로 적용될 수 없습니다. 이 색인은 다음에만 있기 때문입니다.고유1열. 대신 인덱스로 검색된 행에 필터로 적용됩니다. 따라서 이 추가 확인을 반영하여 실제로 비용이 약간 증가했습니다.

어떤 경우에는 기획자가 다음을 선호할 것입니다.간단한색인 스캔 계획:

설명 선택 * FROM tenk1 WHERE 고유1 = 42;

                                 쿼리 계획
----------------------------------------------------------------
 tenk1에서 tenk1_unique1을 사용하는 인덱스 스캔(비용=0.29..8.30행=1너비=244)
   인덱스 조건: (unique1 = 42)

이 유형의 계획에서는 테이블 행을 색인 순서로 가져오므로 읽기 비용이 더 많이 들지만 행 위치를 정렬하는 데 드는 추가 비용이 너무 적기 때문에 그럴 가치가 없습니다. 단일 행만 가져오는 쿼리에 대해 이 계획 유형을 가장 자주 볼 수 있습니다. 또한 다음이 있는 쿼리에도 자주 사용됩니다.주문 기준색인 순서와 일치하는 조건입니다. 그 이유는 다음을 만족시키기 위해 추가 정렬 단계가 필요하지 않기 때문입니다.주문 기준.

에서 참조된 여러 열에 별도의 색인이 있는 경우어디에서, 플래너는 인덱스의 AND 또는 OR 조합을 사용하도록 선택할 수 있습니다.

설명 선택 * FROM tenk1 여기서 고유1 < 100 AND 고유2  9000;

                                     쿼리 계획
------------------------------------------------------------------------
 tenk1의 비트맵 힙 스캔(비용=25.08..60.21행=10너비=244)
   조건을 다시 확인하세요: ((unique1 < 100) AND (unique2  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)
               지수 조건: (unique2  9000)

그러나 이를 위해서는 두 인덱스를 모두 방문해야 하므로 하나의 인덱스만 사용하고 다른 조건을 필터로 처리하는 것에 비해 반드시 승리하는 것은 아닙니다. 관련된 범위를 변경하면 그에 따라 계획이 변경되는 것을 볼 수 있습니다.

다음은 효과를 보여주는 예입니다제한:

설명 선택 * FROM tenk1 여기서 고유1 < 100 AND 고유2  9000 제한 2;

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

이것은 위와 동일한 쿼리이지만 다음을 추가했습니다.제한그래서 모든 행을 검색할 필요는 없으며 플래너는 무엇을 해야할지에 대한 마음을 바꿨습니다. Index Scan 노드의 총 비용과 행 수가 실행이 완료된 것처럼 표시됩니다. 그러나 Limit 노드는 해당 행의 5분의 1만 검색한 후에 중지될 것으로 예상되므로 총 비용은 5분의 1에 불과하며 이것이 쿼리의 실제 예상 비용입니다. 이 계획은 이전 계획에 Limit 노드를 추가하는 것보다 선호됩니다. 왜냐하면 Limit은 비트맵 스캔의 시작 비용 지불을 피할 수 없으므로 이 접근 방식을 사용하면 총 비용이 25단위 이상이 되기 때문입니다.

우리가 논의한 열을 토토 커뮤니티하여 두 테이블을 조인해 보겠습니다.

설명 선택 *
tenk1 t1, tenk2 t2에서
t1.unique1 < 10 AND t1.unique2 = t2.unique2;

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

이 계획에는 두 개의 테이블 스캔을 입력 또는 하위로 포함하는 중첩 루프 조인 노드가 있습니다. 노드 요약 줄의 들여쓰기는 계획 트리 구조를 반영합니다. 조인이 첫 번째이거나외부, child는 이전에 본 것과 유사한 비트맵 스캔입니다. 비용과 행 개수는 우리가 얻은 것과 동일합니다.선택 ... 고유한 위치1 < 10우리는 다음을 적용하고 있기 때문에어디고유1 < 10그 노드에서.t1.unique2 = t2.unique2절은 아직 관련이 없으므로 외부 스캔의 행 수에 영향을 주지 않습니다. 중첩 루프 조인 노드는 두 번째를 실행합니다. 또는내부자식은 외부 하위에서 얻은 각 행에 대해 한 번입니다. 현재 외부 행의 열 값을 내부 스캔에 연결할 수 있습니다. 여기,t1.unique2바깥쪽 행의 값을 토토 커뮤니티할 수 있으므로 위에서 본 것과 유사한 계획과 비용을 얻습니다.선택 ... 어디서 t2.unique2 =상수케이스. (반복적인 인덱스 스캔 중에 발생할 것으로 예상되는 캐싱의 결과로 예상 비용은 위에서 본 것보다 실제로 약간 낮습니다.t2.) 그런 다음 루프 노드의 비용은 외부 스캔 비용, 각 외부 행(여기서는 10 * 7.91)에 대한 내부 스캔 1회 반복, 조인 처리를 위한 약간의 CPU 시간을 기준으로 설정됩니다.

이 예에서 조인의 출력 행 수는 두 스캔의 행 수의 곱과 동일하지만 추가 항목이 있을 수 있으므로 모든 경우에 해당되는 것은 아닙니다.어디에서절은 두 테이블을 모두 언급하므로 두 입력 스캔이 아닌 조인 포인트에만 적용될 수 있습니다. 예를 들면 다음과 같습니다.

설명 선택 *
tenk1 t1, tenk2 t2에서
t1.unique1 < 10 AND t2.unique2 < 10 AND t1.hundred < t2.hundred;

                                         쿼리 계획
--------------------------------------------------------------------------------
 중첩 루프(비용=4.65..49.46행=33너비=488)
   조인 필터: (t1.hundred < t2.hundred)
   - tenk1 t1의 비트맵 힙 스캔(비용=4.36..39.47 행=10 너비=244)
         조건 재확인: (unique1 < 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)
               지수 조건: (unique2 < 10)

조건t1.백 < t2.백다음에서는 테스트할 수 없습니다.tenk2_unique2색인이므로 조인 노드에 적용됩니다. 이렇게 하면 조인 노드의 예상 출력 행 수가 줄어들지만 입력 스캔은 변경되지 않습니다.

여기서 기획자가 선택했음을 주목하세요.구현하다조인의 내부 관계, 그 위에 Materialise 계획 노드를 배치합니다. 이는 다음을 의미합니다.t2중첩 루프 조인 노드가 외부 관계의 각 행에 대해 한 번씩 해당 데이터를 10번 읽어야 하더라도 인덱스 스캔은 한 번만 수행됩니다. Materialize 노드는 데이터를 읽을 때 메모리에 저장한 다음 각 후속 패스에서 메모리의 데이터를 반환합니다.

외부 조인을 처리할 때 두 가지가 모두 포함된 조인 계획 노드를 볼 수 있습니다.조인 필터그리고 일반필터조건이 첨부되었습니다. 조인 필터 조건은 외부 조인에서 나옵니다.켜짐절이므로 조인 필터 조건에 실패한 행은 여전히 null 확장 행으로 내보내질 수 있습니다. 그러나 일반 필터 조건은 외부 조인 규칙 뒤에 적용되므로 무조건 행을 제거하는 역할을 합니다. 내부 조인에서는 이러한 유형의 필터 간에 의미상 차이가 없습니다.

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

설명 선택 *
tenk1 t1, tenk2 t2에서
t1.unique1 < 100 AND t1.unique2 = t2.unique2;

                                        쿼리 계획
-----------------------------------------------------------------------------
 해시 조인(비용=230.47..713.98행=101너비=488)
   해시 조건: (t2.unique2 = t1.unique2)
   - tenk2 t2의 시퀀스 스캔(비용=0.00..445.00 행=10000 너비=244)
   - 해시(비용=229.20..229.20행=101 너비=244)
         - tenk1 t1의 비트맵 힙 스캔(비용=5.07..229.20 행=101 너비=244)
               조건 재확인: (unique1 < 100)
               - tenk1_unique1의 비트맵 인덱스 스캔(비용=0.00..5.04행=101 너비=0)
                     인덱스 조건: (unique1 < 100)

여기서 플래너는 해시 조인을 사용하기로 선택했습니다. 이 방식에서는 한 테이블의 행이 메모리 내 해시 테이블에 입력된 후 다른 테이블이 스캔되고 해시 테이블이 각 행과 일치하는지 조사됩니다. 들여쓰기가 계획 구조를 어떻게 반영하는지 다시 한 번 주목하세요: 비트맵 스캔 온tenk1은 해시 테이블을 구성하는 해시 노드에 대한 입력입니다. 그런 다음 Hash Join 노드로 반환되어 외부 하위 계획에서 행을 읽고 해시 테이블에서 각 항목을 검색합니다.

또 다른 가능한 조인 유형은 병합 조인입니다. 여기에 설명되어 있습니다.

설명 선택 *
tenk1 t1, onek t2에서
t1.unique1 < 100 AND t1.unique2 = t2.unique2;

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

병합 조인은 조인 키에 따라 입력 데이터를 정렬해야 합니다. 이 계획에서는tenk1데이터는 인덱스 스캔을 토토 커뮤니티하여 올바른 순서로 행을 방문하여 정렬되지만 순차 스캔 및 정렬이 선호됩니다.오네크, 해당 테이블에 방문할 행이 더 많기 때문입니다. (순차 스캔 및 정렬은 인덱스 스캔에 필요한 비순차적 디스크 액세스로 인해 많은 행을 정렬할 때 인덱스 스캔보다 자주 능가합니다.)

변형 계획을 보는 한 가지 방법은 다음에 설명된 활성화/비활성화 플래그를 사용하여 가장 저렴하다고 생각되는 전략을 무시하도록 플래너를 강제하는 것입니다.섹션 19.7.1. (이것은 조잡한 도구이지만 유용합니다. 또한 참조하십시오.PostgreSQL : 문서 : 10 : 14.3. 명백한 토토 핫 조항으로 플래너 제어.) 예를 들어, 순차적 스캔 및 정렬이 테이블을 처리하는 가장 좋은 방법이라고 확신하지 못하는 경우오네크이전 예에서는 시도해 볼 수 있습니다.

SET 활성화_정렬 = 꺼짐;

설명 선택 *
tenk1 t1, onek t2에서
t1.unique1 < 100 AND t1.unique2 = t2.unique2;

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

플래너가 정렬을 생각하고 있음을 보여줍니다.오네크인덱스 스캔은 순차 스캔 및 정렬보다 약 12% 더 비쌉니다. 물론 그 다음 질문은 그것이 맞는지 여부이다. 우리는 다음을 사용하여 조사할 수 있습니다.분석 설명, 아래에 설명되어 있습니다.

14.1.2. 분석 설명

다음을 사용하여 기획자의 추정의 정확성을 확인할 수 있습니다.설명's분석옵션. 이 옵션을 토토 커뮤니티하면,설명실제로 쿼리를 실행한 다음 일반 노드와 동일한 추정치와 함께 각 계획 노드 내에 누적된 실제 행 수와 실제 런타임을 표시합니다.설명쇼. 예를 들어 다음과 같은 결과를 얻을 수 있습니다.

설명 분석 선택 *
tenk1 t1, tenk2 t2에서
t1.unique1 < 10 AND 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)
         조건 재확인: (unique1 < 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)
         인덱스 조건: (unique2 = t1.unique2)
 계획 시간: 0.181ms
 실행 시간: 0.501ms

참고하세요실제 시간값은 실시간의 밀리초 단위인 반면,비용추정치는 임의의 단위로 표현됩니다. 그래서 그들은 일치하지 않을 것 같습니다. 일반적으로 찾아야 할 가장 중요한 것은 예상 행 수가 현실에 가까운지 여부입니다. 이 예에서는 추정치가 모두 틀렸지만 실제로는 매우 이례적입니다.

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

어떤 경우에는분석 설명계획 노드 실행 시간 및 행 수 이외의 추가 실행 통계를 표시합니다. 예를 들어 Sort 및 Hash 노드는 추가 정보를 제공합니다.

설명 분석 선택 *
tenk1 t1, tenk2 t2에서
t1.unique1 < 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous;

                                                                 쿼리 계획
------------------------------------------------------------------------------------------------------------------
 정렬(비용=717.34..717.59 행=101 너비=488) (실제 시간=7.761..7.774 행=100 루프=1)
   정렬 키: t1.fivethous
   정렬 방법: 퀵소트 메모리: 77kB
   - 해시 조인(비용=230.47..713.98 행=101 너비=488) (실제 시간=0.711..7.427 행=100 루프=1)
         해시 조건: (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)
                     조건 재확인: (unique1 < 100)
                     - tenk1_unique1의 비트맵 인덱스 스캔(비용=0.00..5.04 행=101 너비=0)(실제 시간=0.049..0.049 행=100 루프=1)
                           지수 조건: (고유1 < 100)
 계획 시간: 0.194ms
 실행 시간: 8.008ms

정렬 노드는 토토 커뮤니티된 정렬 방법(특히 정렬이 메모리 내 또는 디스크 내 정렬인지 여부)과 필요한 메모리 양 또는 디스크 공간을 표시합니다. 해시 노드에는 해시 버킷 및 배치 수와 해시 테이블에 토토 커뮤니티된 최대 메모리 양이 표시됩니다. (배치 수가 1개를 초과하면 디스크 공간 토토 커뮤니티량도 포함되지만 표시되지 않습니다.)

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

설명 분석 선택 * FROM tenk1 WHERE ten < 7;

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

이러한 수는 조인 노드에 적용된 필터 조건에 특히 유용할 수 있습니다.행이 제거됨라인은 하나 이상의 스캔된 행 또는 조인 노드의 경우 잠재적인 조인 쌍이 필터 조건에 의해 거부된 경우에만 나타납니다.

필터 조건과 유사한 경우가 발생함손실색인 스캔. 예를 들어, 특정 점을 포함하는 다각형에 대한 다음 검색을 고려해보세요.

설명 분석 선택 * FROM 다각형_tbl WHERE f1 @ 다각형 '(0.5,2.0)';

                                              쿼리 계획
----------------------------------------------------------------------------
 Polygon_tbl의 시퀀스 스캔(비용=0.00..1.05행=1 너비=32)(실제 시간=0.044..0.044행=0 루프=1)
   필터: (f1 @ '((0.5,2))'::폴리곤)
   필터에 의해 제거된 행: 4
 계획 시간: 0.040ms
 실행 시간: 0.083ms

플래너는 이 샘플 테이블이 인덱스 스캔을 수행하기에는 너무 작다고 (아주 정확하게) 생각하므로 필터 조건에 의해 모든 행이 거부되는 일반 순차 스캔이 있습니다. 그러나 인덱스 스캔을 강제로 사용하면 다음과 같은 결과가 나타납니다.

SET 활성화_seqscan TO 끄기;

설명 분석 선택 * FROM 폴리곤_tbl WHERE 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.144ms

여기서 우리는 인덱스가 하나의 후보 행을 반환한 것을 볼 수 있으며, 이는 인덱스 조건 재검사에 의해 거부되었습니다. 이는 GiST 인덱스가 다음과 같기 때문에 발생합니다.손실다각형 포함 테스트의 경우: 실제로 대상과 겹치는 다각형이 있는 행을 반환한 다음 해당 행에 대해 정확한 포함 테스트를 수행해야 합니다.

설명버퍼함께 토토 커뮤니티할 수 있는 옵션분석더 많은 런타임 통계를 얻으려면:

설명(분석, 버퍼) SELECT * FROM tenk1 WHERE 고유1 < 100 AND 고유2  9000;

                                                           쿼리 계획
---------------------------------------------------------------------------------------------------------------------------------
 tenk1의 비트맵 힙 스캔(비용=25.08..60.21 행=10 너비=244)(실제 시간=0.323..0.342 행=10 루프=1)
   조건을 다시 확인하세요: ((unique1 < 100) AND (unique2  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)
               인덱스 조건: (unique2  9000)
               버퍼: 공유 적중=5
 계획 시간: 0.088ms
 실행 시간: 0.423ms

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

이것을 명심하세요 왜냐하면분석 설명실제로 쿼리를 실행하면 쿼리에서 출력할 수 있는 결과가 무엇이든 인쇄를 위해 폐기되더라도 모든 부작용은 평소와 같이 발생합니다.설명데이터. 테이블을 변경하지 않고 데이터 수정 쿼리를 분석하려면 나중에 명령을 롤백할 수 있습니다. 예를 들면 다음과 같습니다.

시작;

설명 분석 업데이트 tenk1 SET 100 = 100 + 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)
         조건 재확인: (unique1 < 100)
         - tenk1_unique1의 비트맵 인덱스 스캔(비용=0.00..5.04 행=101 너비=0)(실제 시간=0.043..0.043 행=100 루프=1)
               지수 조건: (고유1 < 100)
 계획 시간: 0.079ms
 실행 시간: 14.727ms

롤백;

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

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

EXPLAIN UPDATE 상위 SET f2 = f2 + 1 WHERE f1 = 101;
                                    쿼리 계획
----------------------------------------------------------------------
 상위 업데이트(비용=0.00..24.53행=4너비=14)
   상위 업데이트
   child1 업데이트
   child2 업데이트
   child3 업데이트
   - 상위 시퀀스 스캔(비용=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)

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

계획 시간표시자:분석 설명은 구문 분석된 쿼리에서 쿼리 계획을 생성하고 최적화하는 데 걸린 시간입니다. 구문 분석이나 재작성은 포함되지 않습니다.

실행 시간표시자:분석 설명실행기 시작 및 종료 시간과 실행된 트리거를 실행하는 시간이 포함되지만 구문 분석, 재작성 또는 계획 시간은 포함되지 않습니다. 실행에 소요된 시간이전트리거가 있는 경우 관련 삽입, 업데이트 또는 삭제 노드의 시간에 포함됩니다. 하지만 실행에 소요된 시간이후트리거는 거기에 포함되지 않습니다. 왜냐하면이후트리거는 전체 계획이 완료된 후 실행됩니다. 각 트리거에 소요된 총 시간(둘 중 하나)이전또는이후)도 별도로 표시됩니다. 지연된 제약 조건 트리거는 트랜잭션이 끝날 때까지 실행되지 않으므로 전혀 고려되지 않습니다.분석 설명.

14.1.3. 주의사항

실행 시간을 측정하는 두 가지 중요한 방법이 있습니다.분석 설명동일한 쿼리의 정상적인 실행에서 벗어날 수 있습니다. 첫째, 출력 행이 클라이언트에 전달되지 않으므로 네트워크 전송 비용과 I/O 변환 비용은 포함되지 않습니다. 둘째, 다음으로 추가된 측정 오버헤드입니다.분석 설명특히 속도가 느린 시스템에서는 중요할 수 있습니다.gettimeofday()운영 체제 호출. 다음을 사용할 수 있습니다.pg_test_timi토토 커뮤니티시스템의 타이밍 오버헤드를 측정하는 도구입니다.

설명결과는 실제로 테스트하고 있는 상황과 크게 다른 상황으로 추정되어서는 안 됩니다. 예를 들어, 장난감 크기 테이블의 결과를 큰 테이블에 적용한다고 가정할 수 없습니다. 플래너의 비용 추정은 선형적이지 않으므로 더 크거나 작은 테이블에 대해 다른 계획을 선택할 수 있습니다. 극단적인 예는 하나의 디스크 페이지만 차지하는 테이블에서 인덱스 사용 가능 여부에 관계없이 거의 항상 순차 스캔 계획을 얻게 된다는 것입니다. 플래너는 어떤 경우든 테이블을 처리하기 위해 한 번의 디스크 페이지 읽기가 필요하다는 것을 인식하므로 인덱스를 보기 위해 추가 페이지 읽기를 확장하는 것은 가치가 없습니다. (우리는 이런 일이 일어나는 것을 보았습니다.polygon_tbl위의 예.)

실제값과 추정값이 잘 일치하지 않는 경우가 있지만 실제로 잘못된 것은 아닙니다. 그러한 경우 중 하나는 계획 노드 실행이 a에 의해 중단될 때 발생합니다.제한또는 유사한 효과. 예를 들어,제한이전에 사용했던 쿼리

설명 분석 선택 * FROM tenk1 여기서 고유1 < 100 AND 고유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)
         인덱스 조건: (unique2  9000)
         필터: (고유1 < 100)
         필터에 의해 제거된 행: 287
 계획 시간: 0.096ms
 실행 시간: 0.336ms

인덱스 스캔 노드의 예상 비용 및 행 수가 실행이 완료된 것처럼 표시됩니다. 그러나 실제로는 Limit 노드가 2개를 얻은 후 행 요청을 중단했으므로 실제 행 개수는 2개에 불과하고 실행 시간은 예상 비용보다 짧습니다. 이는 추정 오류가 아니며 추정값과 실제 값이 표시되는 방식의 불일치일 뿐입니다.

병합 조인에는 부주의한 사용자를 혼란스럽게 할 수 있는 측정 아티팩트도 있습니다. 병합 조인은 다른 입력이 소진되고 한 입력의 다음 키 값이 다른 입력의 마지막 키 값보다 큰 경우 하나의 입력 읽기를 중지합니다. 이 경우 더 이상 일치하는 항목이 없으므로 첫 번째 입력의 나머지 부분을 스캔할 필요가 없습니다. 이로 인해 한 명의 어린이를 모두 읽지 못하게 되며, 위에서 언급한 것과 같은 결과가 나타납니다.제한. 또한 외부(첫 번째) 하위 항목에 중복 키 값이 있는 행이 포함된 경우 내부(두 번째) 하위 항목이 백업되고 해당 키 값과 일치하는 행 부분을 다시 검색합니다.분석 설명동일한 내부 행의 반복 방출을 마치 실제 추가 행인 것처럼 계산합니다. 외부 중복이 많은 경우 내부 하위 계획 노드에 대해 보고된 실제 행 수는 실제로 내부 관계에 있는 행 수보다 훨씬 클 수 있습니다.

BitmapAnd 및 BitmapOr 노드는 구현 제한으로 인해 항상 실제 행 수를 0으로 보고합니다.