아래 표시된 예제는에 테이블을 사용합니다.postgresql회귀 테스트 데이터베이스. 또한 이후로분석
통계를 생성하는 동안 임의의 샘플링을 사용하면 새로운 후 결과가 약간 변경됩니다분석
.
매우 간단한 쿼리로 시작합시다 :
설명을 설명하십시오 * Tenk1에서; 쿼리 계획 ---------------------------------------------------------------------------------- Tenk1의 Seq 스캔 (비용 = 0.00..458.00 행 = 10000 너비 = 244)
플래너가 카디널리티를 결정하는 방법Tenk1
Postgresql: Tài liệu: 17: 14.2. Thố토토 사이트 kê được sử dụ토토 사이트 bởi 토토 사이트ười lập kế hoạch이지만 완전성을 위해 여기에서 반복됩니다. 페이지와 행의 수는PG_CLASS
:
relname = 'tenk1'인 pg_class에서 reelpages, reltuples를 선택하십시오. Relpages | 관계 ----------+----------- 358 | 10000
이 숫자는 마지막으로 최신입니다진공
또는분석
테이블에서. 그런 다음 플래너는 테이블의 실제 현재 페이지 수를 가져옵니다 (테이블 스캔이 필요하지 않은 저렴한 작업입니다). 그것이 다르면Relpages
theReltuples
에 따라 현재 열 숫자 추정치에 도달하도록 스케일링됩니다. 위의 예에서의 값은Relpages
최신이므로 행 무지개 토토치는와 동일합니다.reltuples
.
범위 조건이있는 예로 넘어 가자여기서
절 :
Tenk1에서 선택 *을 선택하십시오. 쿼리 계획 ------------------------------------------------------------------------------------------ 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
함수는 히스토그램을 검색합니다고유 1
FromPG_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- 버킷 [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
이후Craaaa
MCV 목록에 나타나면 선택성은 가장 일반적인 주파수 목록에서 해당 항목입니다 (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 (mcv_freqs))/(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
what의 지나치게 단순화되었습니다Scalarltsel
실제로; 이제 MCV 사용의 예를 보았으므로 더 자세한 내용을 채울 수 있습니다. 그 이후로 그 예는 그 이후로 정확했습니다.고유 1
는 고유 한 열입니다. MCV가 없습니다 (분명히 다른 값보다 더 일반적인 값은 없습니다). 비 유니 키 열의 경우 일반적으로 히스토그램과 MCV 목록이 모두 있으며히스토그램에는 MCVS로 표시되는 열 모집단 부분이 포함되지 않습니다. 우리는보다 정확한 무지개 토토을 허용하기 때문에 이런 식으로 일을합니다. 이 상황에서Scalarltsel
조건을 직접 적용합니다 (예 :“<1000”)) MCV 목록의 각 값에, 조건이 사실 인 MCV의 주파수를 추가합니다. 이것은 MCV의 테이블 부분 내에서 선택성을 정확하게 추정합니다. 그런 다음 히스토그램은 위와 동일한 방식으로 MCV가 아닌 테이블 부분의 선택성을 추정하기 위해 사용 된 다음 두 숫자를 결합하여 전체 선택성을 추정합니다. 예를 들어, 고려
StringU1 < 'iaaaaaa'에서 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_operator
eqjoinsel
. eqjoinsel
둘 다에 대한 통계 정보를 찾아보세요Tenk2
andTENK1
:
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 |
이 경우 NOMCV정보고유 2
그리고 모든 값은 고유 한 것으로 보이므로 (n_distinct = -1), 우리는 두 관계에 대한 행 카운트 추정치에 의존하는 알고리즘을 사용합니다 (NUM_ROWS, 표시되지 않음, "Tenk")는 열 NULL FRACTION (모두에 대한 제로) :.
selectivity = (1 -null_frac1) * (1 -null_frac2) / max (num_rows1, num_rows2) = (1-0) * (1-0) / max (10000, 10000) = 0.0001
이것은 각 관계에 대해 널 분수를 하나에서 빼고 더 큰 관계의 행 카운트로 나눕니다 (이 값은 비 유니 케이스에서 조정됩니다). 결합이 방출 될 가능성이있는 행의 수는 두 입력의 데카르트 제품의 카디 안 제품으로 계산되며, 선택성을 곱합니다.
rows = (outer_cardinality * inner_cardinality) * 선택성 = (50 * 10000) * 0.0001 = 50
두 열에 대한 MCV 목록이 있었다.eqjoinsel
MCV 목록의 직접 비교를 사용하여 MCV에 의해 표시되는 열 집단의 일부 내에서 조인 선택도를 결정했습니다. 나머지 인구에 대한 추정치는 여기에 표시된 것과 동일한 접근법을 따릅니다.
우리가 보여준 것을 알았습니다Inner_cardinality
as 10000, 즉, 수정되지 않은 크기Tenk2
. 검사에서 나타날 수 있습니다.설명
결합 행의 무지개 토토치가 50 * 1, 즉 외부 행의 수는 각 내부 색인 스캔에서 얻은 무지개 토토 행 수의 횟수Tenk2
. 그러나 이것은 그렇지 않습니다. 조인 관계 크기는 특정 조인 계획이 고려되기 전에 추정됩니다. 모든 것이 잘 작동하는 경우 조인 크기를 추정하는 두 가지 방법은 동일한 답변을 생성하지만, 라운드 오프 오류 및 기타 요인으로 인해 때때로 크게 분기됩니다.
더 자세한 내용에 관심이있는 사람들은 테이블 크기를 추정합니다 (이전여기서
Clauses)에서 수행됩니다SRC/백엔드/최적화/util/plancat.c
. 절정에 대한 일반적인 논리는SRC/백엔드/최적화/PATH/CLAUSESEL.C
. 연산자 별 선택성 함수는 대부분에서 발견됩니다.src/backend/utils/adt/selfuncs.c
.
문서에 올바른 것이없는 것이 있으면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 설명이 필요합니다. 사용이 양식문서 문제를보고하려면