쿼리 성능은 많은 요인에 의해 영향을 받을 수 있습니다. 일부 이것들은 윈 토토자가 조작할 수 있지만 다른 것들은 시스템의 기본 설계의 기본입니다. 이 장 이해와 조정에 대한 몇 가지 힌트를 제공합니다.PostgreSQL성능.
PostgreSQLa를 고안쿼리 계획각 쿼리에 대해 제공됩니다. 쿼리 구조와 쿼리 구조에 맞는 올바른 계획 선택 데이터의 속성은 좋은 결과를 위해 절대적으로 중요합니다. 성능. 다음을 사용할 수 있습니다.설명시스템이 어떤 쿼리 계획을 생성하는지 확인하는 명령 쿼리. 계획 읽기는 광범위한 연구를 할 가치가 있는 예술입니다. 이것은 튜토리얼이 아닙니다. 하지만 여기에는 몇 가지 기본 사항이 있습니다. 정보.
현재 인용되는 숫자설명다음은:
예상 시작 비용(출력까지 소요되는 시간) 스캔이 시작될 수 있습니다(예: 정렬을 수행할 시간). 노드.)
예상 총 비용(모든 행을 검색한 경우, --- a가 포함된 쿼리가 아닐 수도 있습니다.제한절은 지불이 부족할 것입니다 예를 들어 총 비용입니다.)
이 계획 노드에서 출력되는 예상 행 수 (다시 말하지만, 실행이 완료되는 경우에만 해당됩니다.)
다음에 의해 출력된 행의 예상 평균 너비(바이트) 이 계획 노드
비용은 디스크 페이지 가져오기 단위로 측정됩니다. (CPU 노력 추정치는 다음을 사용하여 디스크 페이지 단위로 변환됩니다. 상당히 임의적인 퍼지 요인. 실험해보고 싶다면 이러한 요소는 런타임 구성 목록을 참조하세요. 의 매개변수사설 토토 사이트 PostgreSQL : 문서 : 7.)
상위 노드의 비용은 모든 하위 노드의 비용이 포함됩니다. 그것은 또한 중요하다 비용은 단지 그 비용이 반영하는 것만을 반영한다는 것을 깨닫는 것입니다. 플래너/옵티마이저가 관심을 갖고 있습니다. 특히 비용이 들지 않는다. 결과 행을 전송하는 데 소요된 시간을 고려하십시오. 프론트엔드 --- 이는 게임 내에서 매우 지배적인 요소가 될 수 있습니다. 실제 경과 시간이지만 플래너는 이를 무시합니다. 계획을 변경하여 변경하세요. (모든 올바른 계획이 출력됩니다. 동일한 행 세트를 신뢰합니다.)
행 출력은 약간 까다롭습니다.아님행 수 쿼리에 의해 처리/스캔됨 --- 일반적으로 더 적습니다. 임의의 예상 선택성을 반영함어디-적용 중인 절 제약조건 이 노드에서. 이상적으로 최상위 행 추정치는 실제로 반환, 업데이트 또는 행 수를 대략적으로 계산합니다. 쿼리에 의해 삭제되었습니다.
다음은 몇 가지 예입니다(회귀 테스트 데이터베이스 사용). a 이후진공 분석및 7.3 개발 소스):
regression=# EXPLAIN SELECT * FROM tenk1;
쿼리 계획
------------------------------------------------
tenk1의 시퀀스 스캔(비용=0.00..333.00행=10000너비=148)
이것은 매우 간단합니다. 그렇게 한다면
SELECT * FROM pg_class WHERE relname = 'tenk1';
당신은 그것을 알게 될 것입니다tenk1에는 233개의 디스크 페이지와 10000개의 행이 있습니다. 따라서 비용은 다음과 같이 추정됩니다.
233개 페이지 읽기, 각 비용 1.0 + 10000 *으로 정의됨cpu_tuple_cost현재는
0.01(시도해 보세요)cpu_tuple_cost 표시).
이제 쿼리를 수정하여 다음을 추가하겠습니다.어디조건:
regression=# EXPLAIN SELECT * FROM tenk1 WHERE Unique1 < 1000;
쿼리 계획
----------------------------------
tenk1의 시퀀스 스캔(비용=0.00..358.00행=1033너비=148)
필터: (고유1 < 1000)
다음으로 인해 출력 행의 추정치가 감소했습니다.어디에서절. 그러나 스캔은 여전히 10000개의 행을 모두 방문해야 하므로 비용이 발생하지 않습니다. 감소; 실제로는 추가 금액을 반영하기 위해 약간 올라갔습니다. 확인하는 데 소요된 CPU 시간어디조건.
이 쿼리가 선택하는 실제 행 수는 1000개입니다. 그러나 추정치는 대략적인 것일 뿐입니다. 복제하려고 하면 이 실험에서는 아마도 약간 다른 결과를 얻게 될 것입니다. 추정; 게다가 매번 변경될 것입니다.분석명령, 왜냐하면 통계가 생성되었기 때문입니다. 으로분석무작위로 추출된 것입니다. 테이블 샘플입니다.
조건을 더욱 제한하려면 쿼리를 수정하십시오:
regression=# EXPLAIN SELECT * FROM tenk1 WHERE Unique1 < 50;
쿼리 계획
------------------------------------------------------------------
tenk1에서 tenk1_unique1을 사용하는 인덱스 스캔(비용=0.00..179.33행=49너비=148)
인덱스 조건: (unique1 < 50)
그리고 우리가 만들면 당신은 그것을 보게 될 것입니다어디조건이 충분히 선택적입니다. 계획자는 결국 인덱스 스캔이 인덱스 스캔보다 저렴하다고 결정하게 될 것입니다. 순차 스캔. 이 계획은 50개 행만 방문하면 됩니다. 인덱스 때문에 각각의 사실에도 불구하고 승리합니다. 개별 가져오기는 전체 디스크를 읽는 것보다 비용이 더 많이 듭니다. 페이지를 순차적으로 진행합니다.
다음에 다른 절 추가어디조건:
regression=# EXPLAIN SELECT * FROM tenk1 WHERE Unique1 < 50 AND
회귀-# stringu1 = 'xxx';
쿼리 계획
------------------------------------------------------------------
tenk1에서 tenk1_unique1을 사용하는 인덱스 스캔(비용=0.00..179.45행=1너비=148)
지수 조건: (고유1 < 50)
필터: (stringu1 = 'xxx'::name)
추가된 조항stringu1 = 'xxx'은 출력 행 추정치를 줄이지만 비용은 줄지 않습니다. 여전히 동일한 행 집합을 방문해야 합니다. 주의할 점은stringu1절은 다음과 같이 적용될 수 없습니다. 인덱스 조건(이 인덱스는 다음에만 있으므로고유1열). 대신에 다음과 같이 적용됩니다. 인덱스로 검색된 행을 필터링합니다. 따라서 비용은 실제로 이 추가 금액을 반영하기 위해 약간 상승했습니다. 확인 중입니다.
우리가 설정한 필드를 윈 토토하여 두 테이블을 결합해 보겠습니다. 논의 중:
regression=# EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50
회귀-# AND t1.unique2 = t2.unique2;
쿼리 계획
--------------------------------------------------
중첩 루프(비용=0.00..327.02행=49너비=296)
- tenk1 t1에서 tenk1_unique1을 사용한 인덱스 스캔
(비용=0.00..179.33행=49너비=148)
지수 조건: (고유1 < 50)
- tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔
(비용=0.00..3.01행=1너비=148)
인덱스 조건: ("outer".unique2 = t2.unique2)
이 중첩 루프 조인에서 외부 스캔은 동일한 인덱스입니다 지난번 예에서 스캔한 결과 비용과 행이 표시됩니다. 우리가 적용하기 때문에 개수는 동일합니다.고유1 < 50 어디해당 노드의 절.t1.unique2 = t2.unique2절은 아직 관련이 없으므로 의미가 없습니다. 외부 스캔의 행 수에 영향을 미칩니다. 내부 스캔의 경우,고유2현재의 가치 외부 스캔 행은 내부 인덱스 스캔에 연결되어 생성됩니다. 다음과 같은 인덱스 조건t2.unique2 =상수. 그래서 우리는 예를 들어, 우리가 얻을 수 있는 동일한 내부 스캔 계획 및 비용설명 선택 * FROM tenk2 WHERE Unique2 = 42. 루프 노드의 비용은 다음을 기준으로 설정됩니다. 외부 스캔 비용과 내부 스캔 1회 반복 비용 각 외부 행(여기서는 49 * 3.01)과 약간의 CPU를 스캔합니다. 조인 처리 시간입니다.
이 예에서 루프의 출력 행 개수는 다음과 같습니다. 두 스캔의 행 개수를 곱한 값이지만 이는 사실이 아닙니다. 일반적으로 일반적으로 다음을 가질 수 있기 때문입니다.어디두 관계를 모두 언급하는 절 조인 포인트에만 적용할 수 있으며 두 입력에는 적용할 수 없습니다. 스캔. 예를 들어, 다음을 추가했다면어디에서... AND t1.백 < t2.백, 그러면 조인 노드의 행 수를 출력하지만 입력은 변경하지 않습니다. 스캔하다.
변형 계획을 보는 한 가지 방법은 계획자가 다음을 수행하도록 강제하는 것입니다. 승자라고 생각되는 전략은 무엇이든 무시하고 다음을 사용합니다. 각 계획 유형에 대한 활성화/비활성화 플래그. (이것은 조잡한 것입니다. 도구이지만 유용합니다. 또한 참조하세요섹션 10.3.)
regression=# SET 활성화_nestloop = 꺼짐;
세트
regression=# EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50
회귀-# AND t1.unique2 = t2.unique2;
쿼리 계획
------------------------------------------------
해시 조인(비용=179.45..563.06행=49너비=296)
해시 조건: ("outer".unique2 = "inner".unique2)
- tenk2 t2의 시퀀스 스캔(비용=0.00..333.00 행=10000 너비=148)
- 해시(비용=179.33..179.33행=49너비=148)
- tenk1 t1에서 tenk1_unique1을 사용한 인덱스 스캔
(비용=0.00..179.33행=49너비=148)
인덱스 조건: (unique1 < 50)
이 계획은 50개의 흥미로운 행을 추출하는 것을 제안합니다.tenk1동일한 색인을 사용하고 있습니다
스캔하여 메모리 내 해시 테이블에 저장한 다음
순차 스캔tenk2,
가능한 일치를 찾기 위해 해시 테이블을 조사합니다.t1.unique2 = t2.unique2각각tenk2행. 읽는 비용tenk1해시 테이블 설정은 전적으로
해시 조인의 시작 비용(행을 얻지 못하므로)
우리가 읽기 시작할 수 있을 때까지 기다리세요tenk2. 조인에 대한 총 예상 시간
또한 해시를 조사하는 데 소요되는 CPU 시간에 대한 막대한 요금도 포함됩니다.
테이블 10000 번. 그러나 우리는 다음과 같습니다.아님10000번 충전 179.33;
해시 테이블 설정은 이 계획 유형에서 한 번만 수행됩니다.
기획자의 정확성을 확인할 수 있습니다. 윈 토토에 따른 예상 비용설명하세요 분석. 이 명령은 실제로 쿼리를 실행하고 그런 다음 각 계획 내에서 누적된 실제 실행 시간을 표시합니다. 일반 노드와 동일한 예상 비용과 함께 노드설명표시됩니다. 예를 들어, 다음과 같은 결과를 얻습니다:
regression=# 분석 설명
회귀-# SELECT * FROM tenk1 t1, tenk2 t2
회귀-# WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
쿼리 계획
------------------------------------------------------------------
중첩 루프(비용=0.00..327.02행=49너비=296)
(실제 시간=1.18..29.82행=50루프=1)
- tenk1 t1에서 tenk1_unique1을 사용한 인덱스 스캔
(비용=0.00..179.33행=49너비=148)
(실제 시간=0.63..8.91행=50루프=1)
지수 조건: (고유1 < 50)
- tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔
(비용=0.00..3.01행=1너비=148)
(실제 시간=0.29..0.32행=1루프=50)
인덱스 조건: ("outer".unique2 = t2.unique2)
총 런타임: 31.60msec
참고하세요"실제 시간"값은 실시간의 밀리초 단위인 반면,"비용"추정치는 다음으로 표현됩니다. 임의의 디스크 가져오기 단위; 그래서 그들은 일치하지 않을 것 같습니다 위로. 주목해야 할 것은 비율입니다.
일부 쿼리 계획에서는 하위 계획 노드가 두 번 이상 실행되었습니다. 예를 들어 내부 인덱스 스캔은 다음과 같습니다. 위의 중첩 루프 계획에서 외부 행당 한 번씩 실행됩니다. 에서 그러한 경우에는"루프"값 노드의 총 실행 횟수를 보고합니다. 표시된 실제 시간 및 행 값은 실행당 평균입니다. 이는 숫자를 다음과 같은 방식으로 비교하기 위해 수행됩니다. 예상 비용이 표시됩니다. 를 곱한다"루프"실제로 총 시간을 가져오는 값 노드에서 소비되었습니다.
그총 런타임표시자:분석 설명실행자 포함 시작 및 종료 시간과 처리에 소요된 시간 결과 행. 구문 분석, 재작성 또는 작업은 포함되지 않습니다. 계획 시간. 에 대한선택질의, 총 실행 시간은 일반적으로 최상위 계획 노드에 대해 보고된 총 시간입니다. 에 대한삽입, 업데이트및삭제명령, 총 실행 시간 소요된 시간이 포함되어 있기 때문에 상당히 클 수 있습니다. 결과 행을 처리합니다. 이 명령에서는 최상위 계획 노드는 본질적으로 새로운 것을 계산하는 데 소요되는 시간입니다. 행 및/또는 이전 행을 찾지만 여기에는 변경하는 데 소요된 시간입니다.
그것은 주목할 가치가 있습니다설명결과는 다음 이외의 상황으로 추정되어서는 안 됩니다. 실제로 테스트하고 있는 것; 예를 들어, 장난감 크기의 테이블은 큰 테이블에 적용된다고 가정할 수 없습니다. 는 기획자의 비용 추정은 선형적이지 않으므로 그럴 수도 있습니다. 더 크거나 작은 테이블에 대해서는 다른 계획을 선택하십시오. 안 극단적인 예는 하나의 디스크만 차지하는 테이블의 경우입니다. 페이지에서는 거의 항상 순차 스캔 계획을 얻게 됩니다. 인덱스를 사용할 수 있는지 여부. 기획자는 그걸 깨닫는다. 어떤 방식으로든 테이블을 처리하기 위해 하나의 디스크 페이지를 읽습니다. 이 경우 추가 페이지 읽기를 확장하는 것은 가치가 없습니다. 인덱스를 보세요.