이 문서는 지원되지 않는 버전의 토토 베이을위한 것입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다토토 캔 : 문서 : 17 : 68 장. 플래너가 통계를 토토 베이하는 방법버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

52 장. 플래너의 토토 베이 방식 통계

이 장은에서 다루는 자료를 기반으로합니다.섹션 13.1and토토 핫그리고 어떻게 플래너는 시스템 통계를 토토 베이하여 행 수를 추정합니다. 쿼리의 각 단계가 돌아올 수 있습니다. 이것은 중요한 부분입니다 많은 원시를 제공하는 계획 / 최적화 프로세스 비용 계산을위한 자료.

이 장의 의도는 코드를 문서화하는 것이 아닙니다. 코드 자체에서 더 잘 수행했지만 방법에 대한 개요를 제시합니다. 작동합니다. 이것은 아마도 누군가의 학습 곡선을 용이하게 할 것입니다 그 후 코드를 읽고 싶은 사람. 결과적으로 선택한 접근 방식은 일련의 점진적으로 더 많은 것을 분석하는 것입니다. 복잡한 예.

아래 표시된 출력 및 알고리즘은 버전에서 가져옵니다. 8.0. 이전 (또는 이후) 버전의 동작은 다를 수 있습니다.

52.1. 행 추정 예

회귀 테스트 데이터베이스에서 그려진 예제 토토 베이 매우 간단한 쿼리로 시작하겠습니다.

설명 *에서 10에서 선택하십시오.

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

플래너가 카디널리티를 결정하는 방법Tenk1섹션 13.1, 그러나 그렇습니다 완전성을 위해 여기에서 반복되었습니다. 행의 수가 찾았습니다 에서pg_class:

reltuples, pg_class에서 릴리스를 선택하여 relname = 'tenk1';

 Relpages | 관계
----------+-----------
      345 |     10000

플래너는를 확인합니다.Relpages추정 (이것은 저렴합니다 작동) 및 부정확 한 경우 스케일Reltuples행 추정치를 얻으려면. 이것에서 따라서 그렇지 않습니다.

행 = 10000

범위 조건이있는 예로 넘어 가자여기서절 :

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

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

플래너는를 검사합니다.여기서조항 조건 :

고유 한 <1000

그리고 연산자의 제한 함수를 찾습니다<inpg_operator. 이것은 열에 보관됩니다Oprrest케이스는Scalarltsel. 그만큼Scalarltsel함수 검색 히스토그램고유 1FromPG_STATISTICS- 우리는 따라갈 수 있습니다 이것은 더 간단한 것을 토토 베이하여PG_STATS보기 :

pg_stats에서 histogram_bounds를 선택하십시오 
여기서 tableName = 'tenK1'및 AttName = '고유 한';

                   Histogram_bounds
--------------------------------------------------------------
 1,970,1943,2958,3971,5069,6028,7007,7919,8982,9995

다음으로 히스토그램의 분획"<1000"가 해결되었습니다. 이것은입니다 선택성. 히스토그램은 범위를 동일하게 나눕니다 주파수 버킷, 그래서 우리가해야 할 일은 버킷을 찾는 것입니다. 우리의 가치가 들어가고 계산한다partall이전의 것. 가치 1000은 분명히 두 번째 (970-1943) 버킷에 있습니다. 각 버킷 내부의 값의 선형 분포를 가정합니다. 선택성을 다음과 같이 계산할 수 있습니다.

selectivity = (1 + (1000 -bckt [2] .min)/(bckt [2] .max -bckt [2] .min))/num_bckts
            = (1 + (1000-970)/(1943-970))/10
            = 0.1031

즉, 하나의 전체 버킷과 선형 분율 둘째, 버킷 수로 나눈 값. 추정 번호 이제 행의 제품으로 계산할 수 있습니다. 그리고의 카디널리티Tenk1:

rows = rel_cardinality * 선택성
     = 10000 * 0.1031
     = 1031

다음 평등 조건이있는 예를 고려해 봅시다 그것은여기서절 :

StringU1 = 'ataaaa'에서 10에서 선택 *을 선택하십시오.

                        쿼리 계획
--------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..470.00 행 = 31 너비 = 244)
   필터 : (stringu1 = 'ataaaa':: name)

다시 플래너가를 검사합니다여기서조항 조건 :

stringu1 = 'ataaaa'

그리고 제한 함수를 찾아=,eqsel. 이 경우는 가장 일반적인 값으로 약간 다릅니다 -MCVs는 결정하는 데 토토 베이됩니다 선택성. 추가로 이것들을 살펴 보겠습니다 나중에 유용 할 열 :

null_frac, n_distinct, most_common_vals, most_common_freqs pg_stats를 선택하십시오 
여기서 tableName = 'tenK1'및 AttName = 'StringU1';

null_frac | 0
n_distinct | 672
Most_common_vals | fdaaaa, nhaaaa, ataaaa, bgaaaa, ebaaaa, moaaaa, ndaaaa, owaaaa, bhaaaa, bjaaaa

선택성은 단지 가장 일반적인 주파수 일뿐입니다 (MCF)에 해당합니다 제삼MCV- 'Ataaaa':

선택성 = MCF [3]
            = 0.003

추정 행 수는 이것의 제품 일뿐입니다. 의 카디널리티와 함께Tenk1AS 전에:

행 = 10000 * 0.003
     = 30

설명is 이 이상의 추정 점검으로 인해 하나 더.

이제 동일한 쿼리를 고려하지만 상수는 아닙니다. 에서MCV목록 :

StringU1 = 'xxx'에서 10에서 선택 *을 선택하십시오.

                        쿼리 계획
--------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..470.00 행 = 15 너비 = 244)
   필터 : (stringu1 = 'xxx':: name)

이것은 상당히 다른 문제입니다. 값이있을 때 선택성아님inMCV목록. 접근 방식은 사실을 토토 베이하는 것입니다 가치가 목록에없고 지식과 결합되어 있습니다. 모든 주파수MCVS :

selectivity = (1- sum (mvf))/(num_distinct -num_mcv)
            = (1- (0.0033333 + 0.00333333 + 0.003 + 0.003 + 0.003 
            + 0.003 + 0.003 + 0.003 + 0.00266667 + 0.00266667))/(672-10)
            = 0.001465

즉,의 모든 주파수를 추가하십시오.MCVs에서 하나에서 빼기 때문에 그것은not중 하나 이것들, 그리고에 의해 나뉘어나머지별개의 값. 알아채다 귀무 값이 없으므로 걱정할 필요가 없습니다. 저것들. 예상 행 수는 평소와 같이 계산됩니다.

행 = 10000 * 0.001465
     = 15

더 많은 사례를 고려하기 위해 복잡성을 높이자 의 한 조건보다여기서절 :

tenk1에서 *를 선택하십시오.

                       쿼리 계획
------------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..495.00 행 = 2 너비 = 244)
   필터 : ((고유 1 <1000) 및 (stringu1 = 'xxx':: name))

독립성의 가정과 선택성이 이루어집니다 개별 제한의 곱하기 :

selectivity = selectivity (고유 1 <1000) * selectivity (stringu1 = 'xxx')
            = 0.1031 * 0.001465
            = 0.00015104

행 추정치는 이전과 같이 계산됩니다 :

행 = 10000 * 0.00015104
     = 2

마지막으로 A가 포함 된 쿼리를 검사합니다.JoinA와 함께여기서절 :

설명 *에서 10, Tenk2 T2에서 선택하십시오 
여기서 t1.unique1 <50 및 t1.unique2 = t2.unique2;

                                      쿼리 계획
----------------------------------------------------------------------------------------------------------------
 중첩 루프 (비용 = 0.00..346.90 행 = 51 너비 = 488)
   - tenk1 t1에서 tenk1_unique1을 사용한 인덱스 스캔 (비용 = 0.00..192.57 행 = 51 너비 = 244)
         색인 조건 : (고유 1 <50)
   - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (비용 = 0.00..3.01 행 = 1 너비 = 244)
         색인 조건 : ( "외부".unique2 = t2.unique2)

제한 ONTENK1 "고유 1 <50"가 평가됩니다 중첩 루프 가입 전에. 이것은와 유사하게 처리됩니다 이전 범위 예제. 제한 연산자<isscalarlteqsel이전과 마찬가지로 이번에는 값 50은의 첫 번째 버킷에 있습니다.고유 1히스토그램 :

20728_20922

가입의 제한은 다음과 같습니다.

t2.unique2 = t1.unique2

이것은 결합 방법이 중첩 루프 인 때문입니다.Tenk1외부 루프에 있습니다. 운영자는 우리의 친숙한 것입니다=, 그러나 제한 함수는에서 얻습니다.oprjoin열의pg_operator- iseqjoinsel. 또한 우리는 다음을 사용합니다 둘 다에 대한 통계 정보Tenk2andTenk1:

PG_STATS에서 TableName, NULL_FRAC, N_DISTINCT, MOST_COMMON_VALS를 선택하십시오 
여기서 ( 'tenk1', 'tenk2') 및 attname = '고유 2'  

표준 이름 | null_frac | n_distinct | 대부분의 _common_vals
-----------+----------+--------------------------------
 Tenk1 |         0 |         -1 |
 Tenk2 |         0 |         -1 |

이 경우 아니요MCV정보에 대한 정보고유 2모든 값이 표시되기 때문입니다 고유하므로 우리는 두 관계에 대한 뚜렷한 값의 수 그들의 null 분수 :

selectivity = (1 -null_frac1) * (1 -null_frac2) * min (1/num_distinct1, 1/num_distinct2)
            = (1-0) * (1-0) * min (1/10000, 1/1000)
            = 0.0001

이것은 각각의 관계, 두 개의 별개의 최대 값으로 나눕니다. 값. 결합이 방출 될 가능성이있는 행의 수는 두 사람의 카르테시아 제품의 카디널스로 계산 중첩 루프의 노드는 선택성을 곱한 것 :

rows = (outer_cardinality * inner_cardinality) * 선택성
     = (51 * 10000) * 0.0001
     = 51

자세한 내용에 관심이있는 사람들의 경우 관계의 행 수는SRC/백엔드/최적화/util/plancat.c. 그만큼 절정에 대한 계산 로직SRC/백엔드/최적화/PATH/CLAUSESEL.C. 그만큼 운영자의 실제 구현 및 제한 조치 함수는에서 찾을 수 있습니다.src/backend/utils/adt/selfuncs.c.