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

17장. 이해 성능

쿼리 성능은 많은 요인에 의해 영향을 받을 수 있습니다. 이들 중 일부 다른 것들은 사용자에 의해 조작될 수 있지만 다른 것들은 시스템의 기본 설계.

색인 생성 및 대량 데이터와 같은 일부 성능 문제 로딩은 다른 곳에서 다룹니다. 이 장에서는 다음에 대해 논의할 것입니다.설명명령을 내리면 어떻게 되는지 보여줄 것입니다. 쿼리 세부 사항은 쿼리 계획에 영향을 미칠 수 있으므로 전체 쿼리에 영향을 미칠 수 있습니다. 성능.

사용 중설명

저자:Tom Lane이 작성, 다음 날짜의 이메일에서 작성: 2000-03-27.

계획서 읽기는 튜토리얼을 들을만한 가치가 있는 기술인데 저는 아직 본 적이 없습니다. 글을 쓰는 시간을 가졌습니다. 여기 빠르고 더러운 것이 있습니다 설명.

현재 EXPLAIN에 의해 인용된 숫자는 다음과 같습니다:

  • 예상 시작 사설 토토(출력 스캔이 완료되기까지 소요되는 시간) 시작(예: SORT 노드에서 정렬을 수행할 시간).

  • 예상 총 사설 토토(모든 튜플이 검색된 경우, 그렇지 않을 수도 있습니다. --- LIMIT에서는 총 금액을 지불하지 못할 수도 있습니다. 예를 들어 사설 토토).

  • 이 계획 노드에 의해 출력된 예상 행 수입니다.

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

비용은 디스크 페이지 가져오기 단위로 측정됩니다. (CPU 노력 추정치는 다음을 사용하여 디스크 페이지 단위로 변환됩니다. 상당히 임의적인 퍼지 요인. 참조세트이것을 실험하고 싶다면 참조 페이지를 참조하세요.) 상위 레벨 노드의 비용에는 다음이 포함된다는 점에 유의해야 합니다. 모든 하위 노드의 비용입니다. 그것을 깨닫는 것도 중요하다 비용은 플래너/옵티마이저가 관심을 갖는 사항만 반영합니다. 약. 특히 비용은 소요 시간을 고려하지 않습니다. 결과 튜플을 프런트엔드로 전송합니다. 실제 경과 시간에서는 매우 중요한 요소이지만 계획자는 계획을 변경하여 변경할 수 없기 때문에 이를 무시합니다. (매 올바른 계획은 동일한 튜플 세트를 출력할 것이라고 믿습니다.)

행 출력은 약간 까다롭습니다.아님다음에 의해 처리/스캔된 행 수 쿼리 --- 추정된 선택성을 반영하여 일반적으로 더 적습니다. 이 시점에 적용되는 모든 WHERE 절 제약 조건 노드.

평균 너비는 실제로는 그렇지 않기 때문에 꽤 가짜입니다. 가변 길이 열의 평균 길이에 대해 알고 있습니다. 나는 앞으로는 개선하려고 생각하지만 그렇지 않을 수도 있습니다. 너비가 많이 사용되지 않기 때문에 문제를 해결할 가치가 있습니다.

다음은 몇 가지 예입니다(회귀 테스트 데이터베이스 사용 후 진공 분석 및 거의 7.0 소스):

regression=# 설명 select * from tenk1;
공지: 쿼리 계획:

tenk1의 시퀀스 스캔(비용=0.00..333.00행=10000너비=148)

이것은 가능한 한 간단합니다. 그렇게 한다면

relname = 'tenk1'인 pg_class에서 * 선택;
tenk1에 233개의 디스크 페이지와 10000개의 디스크 페이지가 있다는 것을 알게 될 것입니다. 튜플. 따라서 비용은 1.0으로 정의된 233개의 블록 읽기로 추정됩니다. 각각에 10000 * 현재 0.01인 cpu_tuple_cost를 더합니다(시도)cpu_tuple_cost 표시).

이제 자격 절을 추가하기 위해 쿼리를 수정합시다:

regression=# 설명 select * from tenk1 where Unique1 < 1000;
공지: 쿼리 계획:

tenk1의 시퀀스 스캔(비용=0.00..358.00행=1000 너비=148)
출력 행의 추정치가 다음으로 인해 감소했습니다. WHERE 절. (놀라울 정도로 정확한 추정치는 tenk1은 특히 간단한 경우입니다. --- Unique1 열에는 0에서 9999 사이의 10000개의 개별 값이 있으므로 추정자는 최소 및 최대 열 값 사이의 선형 보간은 중단되었습니다.) 그러나 스캔은 여전히 10000개의 행을 모두 방문해야 하므로 비용은 감소하지 않았습니다. 실제로는 이를 반영하기 위해 약간 상승했습니다. WHERE 조건을 확인하는 데 추가 CPU 시간이 소요됩니다.

쿼리를 수정하여 자격을 더욱 제한하십시오:

regression=# 설명 select * from tenk1 where Unique1 < 100;
공지: 쿼리 계획:

tenk1에서 tenk1_unique1을 사용하는 인덱스 스캔(비용=0.00..89.35행=100너비=148)
WHERE 조건을 만들면 이를 알 수 있습니다 충분히 선택적이라면 기획자는 결국 다음과 같은 결정을 내릴 것입니다. indexscan은 순차 스캔보다 저렴합니다. 이 계획은 오직 인덱스 때문에 100개의 튜플을 방문해야 하므로 그럼에도 불구하고 승리합니다. 각 개별 가져오기에는 비용이 많이 든다는 사실입니다.

자격에 다른 조건을 추가하십시오:

regression=# 설명 select * from tenk1 여기서 고유1 < 100 및
회귀-# stringu1 = 'xxx';
공지: 쿼리 계획:

tenk1에서 tenk1_unique1을 사용하는 인덱스 스캔(비용=0.00..89.60행=1너비=148)
추가된 절 "stringu1 = 'xxx'"는 출력 행을 줄입니다 추정하지만 비용은 아닙니다. 여전히 같은 곳을 방문해야 하기 때문입니다. 튜플 세트.

우리가 설정한 필드를 사용하여 두 테이블을 조인해 보겠습니다. 논의 중:

regression=# 설명 select * from tenk1 t1, tenk2 t2 여기서 t1.unique1 < 100
회귀-# 및 t1.unique2 = t2.unique2;
공지: 쿼리 계획:

중첩 루프(비용=0.00..144.07행=100 너비=296)
  - tenk1 t1에서 tenk1_unique1을 사용한 인덱스 스캔
             (비용=0.00..89.35행=100너비=148)
  - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔
             (비용=0.00..0.53행=1너비=148)

이 중첩 루프 조인에서 외부 스캔은 동일한 인덱스 스캔입니다 지난번 예에서는 비용과 행 개수가 있었습니다. WHERE에 "unique1 < 100"을 적용하기 때문에 동일합니다. 해당 노드의 절. "t1.unique2 = t2.unique2" 절은 그렇지 않습니다. 아직 관련성이 있으므로 외부 스캔의 행 수에는 영향을 미치지 않습니다. 에 대한 내부 스캔, 현재 외부 스캔 튜플의 고유2 값은 다음과 같습니다. 내부 indexscan에 연결하여 다음과 같은 indexqual을 생성합니다. "t2.unique2 =상수". 그래서 우리는 예를 들어, 우리가 얻을 수 있는 것과 동일한 내부 스캔 계획과 비용은 다음과 같습니다. "unique2 = 42인 tenk2에서 *를 선택하는 방법을 설명하세요." 루프 노드의 비용은 외부 스캔 비용에 1을 더한 값을 기준으로 설정됩니다. 각 외부 튜플(100 * 0.53, 여기), 조인 처리를 위한 약간의 CPU 시간이 추가됩니다.

이 예에서 루프의 출력 행 개수는 다음과 같습니다. 두 스캔의 행 개수를 곱한 값이지만 이는 사실이 아닙니다. 일반적으로 다음을 언급하는 WHERE 절을 가질 수 있기 때문입니다. 두 관계 모두 조인 포인트에만 적용될 수 있으며 조인 포인트에는 적용할 수 없습니다. 입력 스캔 중 하나입니다. 예를 들어 "WHERE ... AND t1.hundred < t2.hundred", 그러면 출력 행 수가 줄어듭니다. 조인 노드의 입력 스캔은 변경하지 않습니다.

우리는 기획자가 무시하도록 강요하여 변형 계획을 볼 수 있습니다 어떤 전략이 승자라고 생각했든(아주 조악한 도구지만, 하지만 현재 우리가 갖고 있는 것은 이것이다):

regression=# set 활성화_nestloop = 꺼짐;
변수 설정
회귀=# 설명 select * from tenk1 t1, tenk2 t2 여기서 t1.unique1 < 100
회귀-# 및 t1.unique2 = t2.unique2;
공지: 쿼리 계획:

해시 조인(비용=89.60..574.10행=100너비=296)
  - tenk2 t2의 시퀀스 스캔
               (비용=0.00..333.00행=10000너비=148)
  - 해시(비용=89.35..89.35행=100너비=148)
        - tenk1 t1에서 tenk1_unique1을 사용한 인덱스 스캔
               (비용=0.00..89.35행=100너비=148)
이 계획은 100개의 흥미로운 행을 추출하는 것을 제안합니다. tenk1은 이전과 동일한 인덱스 스캔을 사용하고 이를 메모리 내 저장합니다. 해시 테이블을 검색한 다음 tenk2를 순차적으로 스캔하여 다음을 조사합니다. "t1.unique2 = t2.unique2"와 일치할 수 있는 해시 테이블 각 tenk2 튜플. tenk1을 읽고 해시 테이블을 설정하는 데 드는 비용 해시 조인에 대한 시작 비용은 전적으로 해시 조인에 대한 시작 비용입니다. tenk2를 읽을 수 있을 때까지 튜플을 꺼냅니다. 총 시간 조인 추정치에는 상당히 높은 CPU 요금도 포함되어 있습니다. 해시 테이블을 10000번 조사하는 데 걸리는 시간입니다. 그러나 우리는 89.35의 10000배를 충전하지 않습니다. 해시 테이블 설정은 이 계획 유형에서는 한 번 완료되었습니다.