72.1. 행 토토 커뮤니티 예

아래 표시된 예제는에 테이블을 사용합니다.PostgreSQL회귀 테스트 데이터베이스. 표시된 출력은 버전 8.3에서 가져옵니다. 이전 (또는 이후) 버전의 동작은 다를 수 있습니다. 또한 이후로분석통계를 생성하는 동안 임의의 샘플링을 사용하면 새로운 후에 결과가 약간 변경됩니다분석.

매우 간단한 쿼리로 시작합시다 :

설명을 설명하십시오 * Tenk1에서;

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

플래너가 카디널리티를 결정하는 방법Tenk1PostgreSQL : 문서 : 14 : 14.2. 플래너가 사용하는 메이저 토토 사이트이지만 완전성을 위해 여기에서 반복됩니다. 페이지와 행의 수는pg_class:

relname = 'tenk1'인 pg_class에서 reelpages, reltuples를 선택하십시오.

 Relpages | 관계
----------+-----------
      358 |     10000

이 숫자는 마지막으로 최신입니다진공또는분석테이블에서. 그런 다음 플래너는 테이블의 실제 현재 페이지 수를 가져옵니다 (테이블 스캔이 필요하지 않은 저렴한 작업입니다). 그것이 다르면Relpagesthereltuples에 따라 현재 열 숫자 추정치에 도달하도록 스케일링됩니다. 위의 예에서의 값은Relpages최신 상태이므로 행 토토 커뮤니티치는와 동일합니다.reltuples.

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

select *에서 * tenk1 where 1 <1000;

                                   쿼리 계획
------------------------------------------------------------------------------------------
 Tenk1의 비트 맵 힙 스캔 (비용 = 24.06..394.64 행 = 1007 너비 = 244)
   COND를 다시 확인하십시오 : (고유 1 <1000)
   - tenk1_unique1의 비트 맵 인덱스 스캔 (비용 = 0.00..23.80 행 = 1007 너비 = 0)
         색인 조건 : (고유 1 <1000)

플래너는를 검사합니다.여기서조항 조건 및 연산자의 선택성 함수를 찾습니다<inpg_operator. 이것은 열에 보관됩니다Oprrest,이 경우 항목은입니다.Scalarltsel. 그만큼Scalarltsel함수는 히스토그램을 검색합니다고유 1FromPG_STATISTIC. 수동 쿼리의 경우 더 간단하게 보는 것이 더 편리합니다PG_STATS보기 :

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

                   Histogram_bounds
--------------------------------------------------------------
 0,993,1997,3050,4040,5036,5957,7057,8029,9016,9995

다음에 의해 점유 된 히스토그램의 분획<1000가 해결되었습니다. 이것이 선택성입니다. 히스토그램은 범위를 동일한 주파수 버킷으로 나눕니다. 따라서 우리가해야 할 일은 우리의 값이 들어있는 버킷을 찾는 것입니다part의 |all이전의 것들. 값 1000은 분명히 두 번째 버킷 (993–1997)에 있습니다. 각 버킷 내부의 값의 선형 분포를 가정하면 선택성을 다음과 같이 계산할 수 있습니다.

selectivity = (1 + (1000- 버킷 [2] .min)/(버킷 [2] .max -bucket [2] .min))/num_buckets
            = (1 + (1000-993)/(1997-993))/10
            = 0.100697

즉, 하나의 전체 버킷과 두 번째 양동이의 선형 분율을 버킷의 수로 나눈 값입니다. 토토 커뮤니티 된 행 수는 이제 선택성의 산물로 계산 될 수 있습니다.Tenk1:

rows = rel_cardinality * 선택성
     = 10000 * 0.100697
     = 1007 (반올림)

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

StringU1 = 'craaaa'에서 tenk1에서 선택 *을 선택하십시오.

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

다시 플래너는를 검사합니다.여기서조항 조건 및 선택성 함수를 찾아=,eqsel. 평등 토토 커뮤니티의 경우 히스토그램은 유용하지 않습니다. 대신 목록가장 일반적인 값(MCVs)는 선택성을 결정하는 데 사용됩니다. 나중에 유용 할 추가 열이 포함 된 MCV를 살펴 보겠습니다.

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

null_frac | 0
n_distinct | 676
Most_common_vals | ejaaaa, bbaaaa, craaaa, fcaaaa, feaaaa, gsaaaa, joaaaa, mcaaaa, naaaaa, wgaaaa

이후CraaaaMCV 목록에 나타나면 선택성은 가장 일반적인 주파수 목록에서 해당 항목입니다 (MCFs) :

선택성 = MCF [3]
            = 0.003

이전과 마찬가지로, 추정 된 행 수는 카디널리티의 제품 일뿐입니다.Tenk1:

행 = 10000 * 0.003
     = 30

이제 동일한 쿼리를 고려하지만 상수가없는 상수는MCV목록 :

select * tenk1에서 stringu1 = 'xxx';

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

이것은 상당히 다른 문제입니다. 값이 선택 될 때 선택성을 토토 커뮤니티하는 방법notinMCV목록. 접근 방식은 값이 목록에 없다는 사실을 사용하는 것입니다.MCVS :

selectivity = (1- sum (mvf))/(num_distinct -num_mcv)
            = (1- (0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003 +
                    0.003 + 0.003 + 0.003 + 0.003))/(676-10)
            = 0.0014559

즉,의 모든 주파수를 추가하십시오.MCVs에서 삽입 한 다음로 나누어기타별개의 값. 이는 MCV가 아닌 열의 비율이 다른 모든 뚜렷한 값에 균등하게 분포된다고 가정하는 것입니다. 널 값이 없으므로 그 값에 대해 걱정할 필요가 없습니다 (그렇지 않으면 숫자 분수를 숫자에서 빼냅니다). 예상 행 수는 평소와 같이 계산됩니다.

행 = 10000 * 0.0014559
     = 15 (반올림)

이전 예제고유 한 <1000무엇을 지나치게 단순화했습니다Scalarltsel실제로; 이제 MCV 사용의 예를 보았으므로 더 자세한 내용을 채울 수 있습니다. 그 이후로 그 예는 그 이후로 정확했습니다.고유 1는 고유 한 열입니다. MCV가 없습니다 (분명히 다른 값보다 값은 없습니다). 비 유니 키 열의 경우 일반적으로 히스토그램과 MCV 목록이 모두 있으며히스토그램에는 MCVS로 표시되는 열 모집단의 부분이 포함되어 있지 않습니다. 우리는보다 정확한 토토 커뮤니티을 허용하기 때문에 이런 식으로 일을합니다. 이 상황에서Scalarltsel조건을 직접 적용합니다 (예 :<1000)) MCV 목록의 각 값에, 조건이 사실 인 MCV의 주파수를 추가합니다. 이것은 MCV의 테이블 부분 내에서 선택성을 정확하게 추정합니다. 그런 다음 히스토그램은 위와 동일한 방식으로 MCV가 아닌 테이블 부분의 선택성을 추정하기 위해 사용 된 다음 두 숫자를 결합하여 전체 선택성을 추정합니다. 예를 들어, 고려

StringU1 < 'iaaaaa'에서 tenk1에서 선택 *을 선택하십시오.

                         쿼리 계획
-------------------------------------------------------------------
 Tenk1의 Seq 스캔 (비용 = 0.00..483.00 행 = 3077 너비 = 244)
   필터 : (stringu1 < 'iaaaaa':: name)

우리는 이미 MCV 정보를 보았습니다StringU1, 그리고 여기에 히스토그램이 있습니다 :

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

                                Histogram_bounds
------------------------------------------------------------------------------------------
 aaaaaa, cqaaaa, fraaaa, ibaaaa, kraaaa, nfaaaa, psaaaa, sgaaaa, vaaaaa, xlaaaa, zzaaaa

MCV 목록 확인, 조건이 있음을 알 수 있습니다StringU1 < 'iaaaaa'마지막 4 개가 아닌 첫 6 개의 항목에 의해 만족되므로 인구의 MCV 부분 내의 선택성은입니다.

selectivity = sum (관련 mvfs)
            = 0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003
            = 0.01833333

모든 MCFS를 합산하면 MCVS로 표시되는 모집단의 총 분획이 0.03033333이므로 히스토그램으로 표시되는 분획은 0.96966667입니다 (다시 말하지만, 여기에 제외해야합니다). 우리는 가치를 볼 수 있습니다IAAAAA세 번째 히스토그램 버킷의 끝에 거의 떨어집니다. 다른 문자의 빈도에 대한 다소 치열한 가정을 사용하여 플래너는 히스토그램 모집단 부분에 대해에 대한 추정치 0.298387에 도달합니다.IAAAAA. 그런 다음 MCV 및 비 MCV 인구에 대한 추정치를 결합합니다.

selectivity = mcv_selectivity + histogram_selectivity * histogram_fraction
            = 0.0183333 + 0.298387 * 0.96966667
            = 0.307669

행 = 10000 * 0.307669
            = 3077 (반올림)

이 특정 예에서 MCV 목록의 수정은 상당히 작습니다. 열 분포는 실제로 상당히 평평하기 때문에 (이러한 특정 값을 보여주는 통계는 다른 것보다 더 일반적이라는 통계가 주로 샘플링 오류로 인한 것입니다). 일부 값보다 일부 값이 다른 값보다 훨씬 일반적인 경우,이 복잡한 프로세스는 가장 일반적인 값의 선택성이 정확히 발견되기 때문에 정확도가 유용한 개선을 제공합니다..

이제에 둘 이상의 조건이있는 사례를 고려해 봅시다여기서절 :

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

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

플래너는 두 조건이 독립적이라고 가정하므로 조항의 개별 선택성에 함께 곱할 수 있습니다.

selectivity = selectivity (고유 1 <1000) * selectivity (stringu1 = 'xxx')
            = 0.100697 * 0.0014559
            = 0.0001466

행 = 10000 * 0.0001466
            = 1 (반올림)

비트 맵 인덱스 스캔에서 반환 된 것으로 토토 커뮤니티 된 행 수는 인덱스와 함께 사용 된 조건 만 반영합니다. 이것은 후속 힙 페치의 비용 토토 커뮤니티치에 영향을 미치기 때문에 중요합니다.

마지막으로 우리는 조인과 관련된 쿼리를 검사합니다 :

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

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

제한 ONTenk1, 고유 한 <50, 중첩 루프 가입 전에 평가됩니다. 이것은 이전 범위 예제와 유사하게 처리됩니다. 이번에는 값 50이의 첫 번째 버킷으로 떨어집니다고유 1히스토그램 :

selectivity = (0 + (50- 버킷 [1] .min)/(버킷 [1] .max- 버킷 [1] .min))/num_buckets
            = (0 + (50-0)/(993-0))/10
            = 0.005035

행 = 10000 * 0.005035
            = 50 (반올림)

가입 제한은입니다.t2.unique2 = t1.unique2. 운영자는 우리의 친숙한 것입니다=, 그러나 선택성 함수는에서 얻습니다.oprjoin열의pg_operatoriseqjoinsel. eqjoinsel두 가지 모두에 대한 통계 정보를 찾습니다Tenk2andTenk1:

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

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

이 경우 아무도 없습니다MCV정보에 대한 정보고유 2모든 값은 고유 한 것처럼 보이므로 두 관계에 대한 별개의 값 수에만 의존하는 알고리즘을 사용합니다.

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

이것은 각 관계에 대해 널 분수를 하나에서 빼고 별개의 값의 최대 값으로 나눕니다. 결합이 방출 될 가능성이있는 행의 수는 두 입력의 데카르트 제품의 카디 안 제품으로 계산되며, 선택성을 곱합니다.

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

두 열에 대한 MCV 목록이 있었다.eqjoinselMCV 목록의 직접 비교를 사용하여 MCV에 의해 표시되는 열 집단의 일부 내에서 조인 선택성을 결정했습니다. 나머지 인구에 대한 추정치는 여기에 표시된 것과 동일한 접근법을 따릅니다.

우리가 보여준 주목Inner_cardinalityas 10000, 즉, 수정되지 않은 크기Tenk2. 검사에서 나타날 수 있습니다.설명결합 행의 토토 커뮤니티치가 50 * 1에서 나온다는 출력Tenk2. 그러나 이것은 그렇지 않습니다. 조인 관계 크기는 특정 조인 계획이 고려되기 전에 추정됩니다. 모든 것이 잘 작동한다면 조인 크기를 추정하는 두 가지 방법은 동일한 답변을 생성하지만 반올림 오류 및 기타 요인으로 인해 때때로 크게 분기됩니다.

더 자세한 내용에 관심이있는 사람들의 경우 테이블 크기에 대한 추정 (이전여기서Clauses)에서SRC/백엔드/최적화/util/plancat.c. 절정에 대한 일반적인 논리는SRC/백엔드/최적화/PATH/CLAUSESEL.C. 연산자 별 선택성 함수는 대부분에서 발견됩니다.src/backend/utils/adt/selfuncs.c.

수정 제출

29007_29233이 양식문서 문제를보고하려면