PostgreSQL 의 bitmap scan 분석
6342 단어 PostgreSQL
bill=# explain select * from t1 where c1=10;
QUERY PLAN
--------------------------------------------------------------------
Index Scan using idx_t1 on t1 (cost=0.15..10.73 rows=10 width=12)
Index Cond: (c1 = 10)
(2 rows)
여러 개의 단일 색인 이 조합 조회 SQL 에 사용 되 는 상황 에서 우 리 는 bitmap scan 을 사용 하 는 것 을 볼 수 있 습 니 다. 예 를 들 어:
bill=# create index idx_t11 on t1 using btree(c1);
CREATE INDEX
bill=# create index idx_t12 on t1 using btree(c2);
CREATE INDEX
bill=# create index idx_t13 on t1 using btree(c3);
CREATE INDEX
bill=# explain select * from t1 where c1 =10 and c2 =20 and c3 = 30;
QUERY PLAN
-----------------------------------------------------------------------------
Bitmap Heap Scan on t1 (cost=3.31..4.62 rows=1 width=12)
Recheck Cond: ((c3 = 30) AND (c2 = 20))
Filter: (c1 = 10)
-> BitmapAnd (cost=3.31..3.31 rows=1 width=0)
-> Bitmap Index Scan on idx_t13 (cost=0.00..1.53 rows=10 width=0)
Index Cond: (c3 = 30)
-> Bitmap Index Scan on idx_t12 (cost=0.00..1.53 rows=10 width=0)
Index Cond: (c2 = 20)
(8 rows)
그렇다면 이 두 가 지 는 어떤 차이 가 있 을 까?PostgreSQL 은 여러 조합 조건 의 BITMAP SCAN 을 어떻게 처리 합 니까?먼저 Index Scan 을 살 펴 보 겠 습 니 다. 이것 은 가장 간단 한 btree 색인 스 캔 입 니 다. 그 원 리 는 색인 key 를 통 해 원 그룹의 ctid 를 찾 은 다음 에 표 로 돌아 가 해당 하 는 데 이 터 를 가 져 오 는 것 입 니 다 (index only scan 제외). BITMAP SCAN 은 모든 검색 조건 에 대해 해당 하 는 색인 에서 조건 에 맞 는 표 PAGE 를 찾 고 색인 마다 bitmap 문자열 을 구성 합 니 다.이 bitmap 문자열 에서 모든 BIT 비트 는 HEAP PAGE 에 대응 합 니 다. 이 HEAP PAGE 에는 이 조건 에 맞 는 줄 이 있 습 니 다 (임의의 줄 이 조건 에 부합 하면 이 PAGE 의 BIT 비트 가 표 시 됩 니 다 1).조건 에 따라 여러 비트 맵 을 구성 하 였 습 니 다.다음 그림 에서 보 듯 이:
+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
|000001000001000100010000000001000010000000010| bitmap 2
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|000000000001000000010000000000000010000000000| Combined bitmap
+-----------+-------+--------------+----------+
| | |
v v v
Used to scan the heap only for matching pages:
+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+
예 를 들 어 우 리 는 c1 열 에 색인 을 만 들 었 습 니 다. 우 리 는 c1 = 10 의 조 회 를 사용 하면 bitmap 1 과 같은 bitmap 문자열 을 만 들 었 습 니 다. 그리고 c2 = 20 에 bitmap 2 와 같은 bitmap 문자열 을 만 든 다음 에 이 두 bitmap 문자열 을 and 로 조작 하여 combined bitmap 와 같은 bitmap 문자열 을 얻 었 습 니 다. 그러나 이때 우 리 는 앞의 실행 계획 에 마지막 으로 Recheck Cond 가 있다 는 것 을 알 게 되 었 습 니 다. 이것 은 무엇 입 니까?앞에서 말 했 듯 이 모든 BIT 비트 는 하나의 HEAP PAGE 에 대응 합 니 다. 우 리 는 모든 page 에 가서 recheck 이 필요 로 하 는 줄 을 얻어 야 합 니 다. 이것 이 바로 Recheck Cond 의 역할 입 니 다. 마지막 으로 어떤 장면 이 bitmap scan 을 사용 하 는 지 살 펴 보 겠 습 니 다.1. 상기 에서 예 를 들 어 btree 색인 의 여러 조합 은 서로 다른 열 및 / 또는 같은 열 을 조회 하 는 or 조 회 를 조회 합 니 다.
2. brin 색인 은 brin 색인 자체 에 저 장 된 것 이 연속 블록 의 메타 정보 이기 때문에 그 자체 가 정확 한 조 회 를 실현 할 수 없 기 때문에 brin 조 회 를 통 해 먼저 힙 페이지 의 bitmap 문자열 을 구축 합 니 다. (조건 에 부합 되 는 것 은 1 이 고 조건 에 부합 되 지 않 는 것 은 0) 그 다음 에 이 bitmap 문자열 에 따라 tuple 을 검색 하고 bitmap heap scan 단계 recheck 조건 을 참조 합 니 다.
bill=# create table t_brin (id int, info text, crt_time timestamp);
CREATE TABLE
bill=# insert into t_brin select generate_series(1,1000000), md5(random()::text), clock_timestamp();
INSERT 0 1000000
bill=# create index idx_t_brin_1 on t_brin using brin (id) with (pages_per_range=1);
CREATE INDEX
bill=# explain (analyze,verbose,timing,costs,buffers) select * from t_brin where id between 100 and 200;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on public.t_brin (cost=38.52..175.79 rows=88 width=45) (actual time=2.100..2.116 rows=101 loops=1)
Output: id, info, crt_time
Recheck Cond: ((t_brin.id >= 100) AND (t_brin.id <= 200))
Rows Removed by Index Recheck: 113
Heap Blocks: lossy=2
Buffers: shared hit=45
-> Bitmap Index Scan on idx_t_brin_1 (cost=0.00..38.50 rows=107 width=0) (actual time=2.082..2.082 rows=20 loops=1)
Index Cond: ((t_brin.id >= 100) AND (t_brin.id <= 200))
Buffers: shared hit=43
Planning Time: 0.224 ms
Execution Time: 2.145 ms
(11 rows)
3. gin 색인 gin 색인 은 KEY 와 ctid (heap 줄 번호) 로 구 성 된 posting list 나 posting tree 를 저장 합 니 다. 이론 적 으로 index scan 을 지원 할 수 있 지만 PostgreSQL 은 현재 GIN 에 만 bitmap scan 을 실시 하고 있 습 니 다.따라서 gin 색인 을 사용 할 때 먼저 힙 페이지 를 구성 하 는 bitmap 문자열 (조건 에 부합 되 는 것 은 1, 조건 에 부합 되 지 않 는 것 은 0) 을 사용 한 다음 에 이 bitmap 문자열 에 따라 tuple 을 검색 하고 bitmap heap scan 단계 에서 recheck 조건 을 검색 합 니 다.이것 도 현재 gin 이 개선 할 만 한 부분 입 니 다.
bill=# create table t_gin2 (id int, c1 int);
CREATE TABLE
bill=# insert into t_gin2 select generate_series(1,100000), random()*10 ;
INSERT 0 100000
bill=# create index idx_t_gin2_1 on t_gin2 using gin (c1);
CREATE INDEX
bill=# explain (analyze,verbose,timing,costs,buffers) select * from t_gin2 where c1=1;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on public.t_gin2 (cost=9.07..349.73 rows=500 width=8) (actual time=1.084..3.279 rows=10038 loops=1)
Output: id, c1
Recheck Cond: (t_gin2.c1 = 1)
Heap Blocks: exact=443
Buffers: shared hit=448
-> Bitmap Index Scan on idx_t_gin2_1 (cost=0.00..8.95 rows=500 width=0) (actual time=1.032..1.032 rows=10038 loops=1)
Index Cond: (t_gin2.c1 = 1)
Buffers: shared hit=5
Planning Time: 0.137 ms
Execution Time: 3.775 ms
(10 rows)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redmine 데이터베이스를 MySQL에서 PostgreSQL로 마이그레이션 (보충)Redmine 의 Database 를 MySQL 로 운용하고 있었습니다만, MySQL 5.6 이상이나 MariaDB 에는 , , 이러한 티켓이 수년 동안 방치된 상황을 감안하여, PostgreSQL로 마이그레이션하기...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.