꽃이 피다다음을 기반으로 하는 색인 액세스 방법을 제공합니다.블룸 필터.
블룸 필터는 요소가 집합의 구성원인지 테스트하는 데 사용되는 공간 효율적인 데이터 구조입니다. 인덱스 액세스 방법의 경우 인덱스 생성 시 크기가 결정되는 시그니처를 통해 일치하지 않는 튜플을 빠르게 제외할 수 있습니다.
서명은 색인된 속성의 손실 표현이므로 잘못된 긍정을 보고하는 경향이 있습니다. 즉, 집합에 포함되지 않은 요소가 포함되어 있다고 보고될 수 있습니다. 따라서 배트맨 토토 검색 결과는 항상 힙 항목의 실제 속성 값을 사용하여 다시 확인해야 합니다. 서명이 클수록 거짓양성(false positive)의 가능성이 줄어들어 불필요한 힙 방문 횟수가 줄어들지만, 물론 배트맨 토토도 커지므로 검색 속도가 느려집니다.
이 유형의 인덱스는 테이블에 많은 속성이 있고 쿼리가 이들의 임의 조합을 테스트할 때 가장 유용합니다. 전통적인 btree 인덱스는 블룸 인덱스보다 빠르지만 단일 블룸 인덱스만 필요한 경우 가능한 모든 쿼리를 지원하려면 많은 btree 인덱스가 필요할 수 있습니다. 그러나 블룸 인덱스는 동등 쿼리만 지원하는 반면, btree 인덱스는 불일치 및 범위 검색도 수행할 수 있습니다.
A 블룸색인은 다음 매개변수를 허용합니다함께절:
길이각 서명(색인 항목)의 길이(비트)입니다. 가장 가까운 의 배수로 반올림됩니다.16. 기본값은80비트이며 최대값은4096.
col1 — col32각 인덱스 열에 대해 생성된 비트 수. 각 매개변수의 이름은 해당 매개변수가 제어하는 인덱스 열의 번호를 나타냅니다. 기본값은2비트이며 최대값은4095. 실제로 사용되지 않는 배트맨 토토 컬럼에 대한 매개변수는 무시됩니다.
이것은 블룸 인덱스 생성의 예입니다:
블룸(i1,i2,i3)을 사용하여 tbloom에서 인덱스 Bloomidx 생성
WITH (길이=80, 열1=2, 열2=2, 열3=4);
인덱스는 80비트의 서명 길이로 생성되며 속성 i1 및 i2는 2비트에 매핑되고 속성 i3은 4비트에 매핑됩니다. 우리는 생략할 수 있었습니다길이, col1및col2기본값이 있으므로 사양입니다.
다음은 블룸 인덱스 정의 및 사용법에 대한 더 완전한 예와 동등한 btree 인덱스와의 비교입니다. 블룸 인덱스는 btree 인덱스보다 상당히 작으며 더 나은 성능을 발휘할 수 있습니다.
=# CREATE TABLE tbloom AS
선택
(random() * 1000000)::int를 i1로,
(random() * 1000000)::int를 i2로,
(random() * 1000000)::int를 i3으로,
(random() * 1000000)::int를 i4로,
(random() * 1000000)::int를 i5로,
(random() * 1000000)::int(i6)
에서
generate_series(1,10000000);
10000000을 선택하세요.
이 큰 테이블에 대한 순차적 스캔에는 시간이 오래 걸립니다.
=# 설명 분석 선택 * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
쿼리 계획
----------------------------------------------------------------------------
tbloom의 Seq 스캔(비용=0.00..213744.00 행=250 너비=24)(실제 시간=357.059..357.059 행=0 루프=1)
필터: ((i2 = 898732) AND (i5 = 123451))
필터에 의해 제거된 행: 10000000
계획 시간: 0.346ms
실행 시간: 357.076ms
(5행)
btree 배트맨 토토가 정의되어 있어도 결과는 여전히 순차 스캔입니다:
=# tbloom에서 btreeidx 배트맨 토토 생성(i1, i2, i3, i4, i5, i6);
배트맨 토토 생성
=# SELECT pg_size_pretty(pg_relation_size('btreeidx'));
pg_size_pretty
----------------
386MB
(1줄)
=# 분석 선택 설명 * tbloom에서 i2 = 898732 AND i5 = 123451;
쿼리 계획
----------------------------------------------------------------------------
tbloom의 Seq 스캔(비용=0.00..213744.00 행=2 너비=24)(실제 시간=351.016..351.017 행=0 루프=1)
필터: ((i2 = 898732) AND (i5 = 123451))
필터에 의해 제거된 행: 10000000
계획 시간: 0.138ms
실행 시간: 351.035ms
(5행)
테이블에 블룸 인덱스를 정의하는 것이 이러한 유형의 검색을 처리하는 데 있어서 btree보다 낫습니다:
=# 블룸(i1, i2, i3, i4, i5, i6)을 사용하여 tbloom에서 인덱스 Bloomidx를 생성합니다.
인덱스 생성
=# SELECT pg_size_pretty(pg_relation_size('bloomidx'));
pg_size_pretty
----------------
153MB
(1줄)
=# 분석 선택 설명 * tbloom에서 i2 = 898732 AND i5 = 123451;
쿼리 계획
--------------------------------------------------------------------------------------------
tbloom의 비트맵 힙 스캔(비용=1792.00..1799.69 행=2 너비=24) (실제 시간=22.605..22.606 행=0 루프=1)
조건 다시 확인: ((i2 = 898732) AND (i5 = 123451))
인덱스 재검사로 제거된 행: 2300
힙 블록: 정확한=2256
- Bloomidx의 비트맵 인덱스 스캔(비용=0.00..178436.00 행=1 너비=0)(실제 시간=20.005..20.005 행=2300 루프=1)
지수 조건: ((i2 = 898732) AND (i5 = 123451))
계획 시간: 0.099ms
실행 시간: 22.632ms
(8행)
이제, btree 검색의 주요 문제는 검색 조건이 선행 인덱스 열을 제한하지 않을 때 btree가 비효율적이라는 것입니다. btree에 대한 더 나은 전략은 각 열에 별도의 인덱스를 만드는 것입니다. 그런 다음 기획자는 다음과 같은 것을 선택합니다.
=# tbloom(i1)에서 배트맨 토토 btreeidx1 생성;
배트맨 토토 생성
=# tbloom(i2)에서 배트맨 토토 btreeidx2 생성;
배트맨 토토 생성
=# tbloom(i3)에서 배트맨 토토 btreeidx3 생성;
배트맨 토토 생성
=# tbloom(i4)에서 배트맨 토토 btreeidx4 생성;
배트맨 토토 생성
=# tbloom(i5)에서 배트맨 토토 btreeidx5 생성;
배트맨 토토 생성
=# tbloom(i6)에서 배트맨 토토 btreeidx6 생성;
배트맨 토토 생성
=# 분석 선택 설명 * tbloom에서 i2 = 898732 AND i5 = 123451;
쿼리 계획
--------------------------------------------------------------------------------------------------
tbloom의 비트맵 힙 스캔(비용=9.29..13.30행=1 너비=24)(실제 시간=0.032..0.033행=0 루프=1)
조건 다시 확인: ((i5 = 123451) AND (i2 = 898732))
- BitmapAnd(비용=9.29..9.29행=1 너비=0)(실제 시간=0.047..0.047행=0 루프=1)
- btreeidx5의 비트맵 배트맨 토토 스캔(비용=0.00..4.52 행=11 너비=0)(실제 시간=0.026..0.026 행=7 루프=1)
지수 조건: (i5 = 123451)
- btreeidx2의 비트맵 배트맨 토토 스캔(비용=0.00..4.52 행=11 너비=0)(실제 시간=0.007..0.007 행=8 루프=1)
지수 조건: (i2 = 898732)
계획 시간: 0.264ms
실행 시간: 0.047ms
(9행)
이 쿼리는 단일 인덱스 중 하나를 사용할 때보다 훨씬 빠르게 실행되지만 인덱스 크기에 있어서 페널티가 발생합니다. 각 단일 열 btree 인덱스는 88.5MB를 차지하므로 필요한 총 공간은 블룸 인덱스에서 사용하는 공간의 3배가 넘는 531MB입니다.
블룸 인덱스에 대한 연산자 클래스에는 인덱스 데이터 유형에 대한 해시 함수와 검색에 대한 항등 연산자만 필요합니다. 이 예는에 대한 연산자 클래스 정의를 보여줍니다.텍스트데이터 유형:
연산자 클래스 생성 text_ops
Bloom AS를 사용하는 유형 텍스트의 기본값
연산자 1 =(텍스트, 텍스트),
기능 1 해시텍스트(텍스트);
다음에 대한 연산자 클래스만int4그리고텍스트모듈에 포함되어 있습니다.
오직=연산자는 검색에 지원됩니다. 하지만 나중에 합집합 및 교차 연산이 포함된 배열에 대한 지원을 추가할 수 있습니다.
블룸액세스 방법이 지원되지 않음고유색인.
블룸액세스 방법은 검색을 지원하지 않습니다.NULL값.
테오도르 시가예프<teodor@postgrespro.ru, Postgres Professional, 러시아 모스크바
알렉산더 코로트코프<a.korotkov@postgrespro.ru, Postgres Professional, 러시아 모스크바
올렉 바르투노프<obartunov@postgrespro.ru, Postgres Professional, 러시아 모스크바
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.