"비트 맵 힙 스캔"및 "비트 맵 인덱스 스캔"이해


36

다음 예를 통해 오해를 설명하려고 노력할 것입니다.

기본 사항 을 이해하지 못했습니다 Bitmap Heap Scan Node. SELECT customerid, username FROM customers WHERE customerid < 1000 AND username <'user100';계획이 다음과 같은 쿼리를 고려하십시오 .

Bitmap Heap Scan on customers  (cost=25.76..61.62 rows=10 width=13) (actual time=0.077..0.077 rows=2 loops=1)
  Recheck Cond: (((username)::text < 'user100'::text) AND (customerid < 1000))
  ->  BitmapAnd  (cost=25.76..25.76 rows=10 width=0) (actual time=0.073..0.073 rows=0 loops=1)
        ->  Bitmap Index Scan on ix_cust_username  (cost=0.00..5.75 rows=200 width=0) (actual time=0.006..0.006 rows=2 loops=1)
              Index Cond: ((username)::text < 'user100'::text)
        ->  Bitmap Index Scan on customers_pkey  (cost=0.00..19.75 rows=1000 width=0) (actual time=0.065..0.065 rows=999 loops=1)
              Index Cond: (customerid < 1000)

이 노드에 대한 나의 이해 :

거기 에 설명 bitmap heap scan된대로 , 읽기 순서대로 테이블 블록을 읽기 때문에 무작위 테이블 액세스 오버 헤드가 발생하지 않습니다 Index Scan.

Index Scan완료된 후 PostgreSQL은 불필요하게 heap blocks reads(또는 hits핫 캐시가있는 경우) 피하기 위해 행을 최적으로 가져 오는 방법을 모릅니다 . 그래서 그것을 알아 내기 위해 인덱스의 두 비트 맵을 생성하고 수행하여 생성 된 구조 ( Bitmap Index Scan)를 생성합니다 . 비트 맵이 생성되었으므로 이제 불필요한 순서를 피하면서 순차적으로 테이블을 최적으로 읽을 수 있습니다 .bitmapBITWISE ANDheap I/O-operations

그것은 많은 질문이 오는 곳입니다.

질문 : 비트 맵이 있습니다. PostgreSQL은 행의 물리적 순서에 대한 비트 맵을 어떻게 알 수 있습니까? 또는 비트 맵을 생성하여 해당 요소를 페이지의 포인터에 쉽게 매핑 할 수 있습니까? 그렇다면 모든 것을 설명하지만 내 추측 일뿐입니다.

그렇다면 우리는 단순히 bitmap heap scan -> bitmap index scan순차적 스캔과 비슷하지만 테이블의 적절한 부분에 불과 하다고 말할 수 있습니까?


나는 이것에 대한 설명을 여기에 썼습니다 : stackoverflow.com/q/33100637/398670
Craig Ringer

@CraigRinger 이해하지 못하는 것을 올바르게 설명하지 않은 것 같습니다. 물론 설명했듯이 PostgreSQL이 순차적으로 테이블을 읽는 비트 맵이 있습니다. 특정 비트 맵으로 지정된 실제 블록을 알아내는 방법을 이해하지 못합니다 (예 :) 001001010101011010101. 또는 실제로 중요하지 않으며 우리가 알아야 할 것은 비트 맵으로 블록을 찾을 수 있다는 것입니다.
St.Antario

아, 여기서 "비트 맵"의 의미를 오해했을 수 있습니다. 편집에서 후속 조치를 취하겠습니다.
Craig Ringer

@CraigRinger 어쩌면 나는 거기 에서 정의를 취했다 .
St.Antario

답변:


52

PostgreSQL은 행의 물리적 순서에 대한 비트 맵을 어떻게 알 수 있습니까?

비트 맵은 힙 페이지 당 1 비트입니다. 비트 맵 인덱스 스캔은 인덱스 항목이 가리키는 힙 페이지 주소를 기반으로 비트를 설정합니다.

따라서 비트 맵 힙 스캔을 수행 할 때는 선형 테이블 스캔 만 수행하여 비트 맵을 읽어 특정 페이지에 신경을 써야하는지 여부를 확인합니다.

또는 비트 맵을 생성하여 해당 요소를 페이지의 포인터에 쉽게 매핑 할 수 있습니까?

아니요, 비트 맵은 힙 페이지와 1 : 1에 해당합니다.

나는이에 좀 더 썼다 여기 .


이 문맥에서 "비트 맵"의 의미를 오해 한 것 같습니다.

"101011"과 같은 비트 문자열은 각 힙 페이지 또는 각 인덱스 읽기 또는 기타에 대해 작성됩니다.

전체 비트 맵은 단일 비트 배열 이며 스캔중인 관계에 힙 페이지가있는 비트 수입니다.

모든 항목 0 (거짓)으로 시작하여 첫 번째 인덱스 스캔에서 하나의 비트 맵이 작성됩니다. 검색 조건과 일치하는 색인 ​​항목이 발견 될 때마다 해당 색인 항목이 가리키는 힙 주소가 비트 맵에 대한 오프셋으로 조회되고 해당 비트는 1 (true)로 설정됩니다. 따라서 비트 맵 인덱스 스캔은 힙 페이지를 직접 조회하지 않고 비트 맵에서 해당 비트 위치를 찾습니다.

두 번째 및 추가 비트 맵 인덱스 스캔은 다른 인덱스 및 검색 조건과 동일한 작업을 수행합니다.

그런 다음 각 비트 맵이 서로 AND됩니다. 결과 비트 맵은 각 힙 페이지에 대해 하나의 비트를 가지며, 비트는 모든 개별 비트 맵 인덱스 스캔, 즉 모든 인덱스 스캔에 대해 일치하는 검색 조건에서 참인 경우에만 참입니다. 로드 및 검사를 위해 귀찮게해야하는 유일한 힙 페이지입니다. 각 힙 페이지에 여러 행이 포함될 수 있으므로 각 행을 검사하여 모든 조건과 일치하는지 확인해야합니다. 이것이 "조건 확인"부분입니다.

이 모든 것을 이해해야 할 한 가지 중요한 점은 인덱스 항목의 튜플 주소가 ctid힙 페이지 번호와 힙 페이지 내 오프셋의 조합 인 행을 가리키는 것입니다. 비트 맵 인덱스 스캔은 오프셋을 무시합니다. 어쨌든 전체 페이지를 확인하고 해당 페이지의 행이 조건과 일치하면 비트를 설정합니다.


그래픽 예

Heap, one square = one page:
+---------------------------------------------+
|c____u_____X___u___X_________u___cXcc______u_|
+---------------------------------------------+
Rows marked c match customers pkey condition.
Rows marked u match username condition.
Rows marked X match both conditions.


Bitmap scan from customers_pkey:
+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
+---------------------------------------------+
One bit per heap page, in the same order as the heap
Bits 1 when condition matches, 0 if not

Bitmap scan from ix_cust_username:
+---------------------------------------------+
|000001000001000100010000000001000010000000010| bitmap 2
+---------------------------------------------+

비트 맵이 만들어지면 비트 AND가 수행됩니다.

+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
|000001000001000100010000000001000010000000010| bitmap 2
 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|000000000001000000010000000000000010000000000| Combined bitmap
+-----------+-------+--------------+----------+
            |       |              |
            v       v              v
Used to scan the heap only for matching pages:
+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+

그런 다음 비트 맵 힙 스캔은 각 페이지의 시작을 찾아 페이지를 읽습니다.

+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+
seek------->^seek-->^seek--------->^
            |       |              |
            ------------------------
            only these pages read

페이지 당> 1 개의 행이있을 수 있고 조건과 반드시 ​​일치하는 것은 아니기 때문에 각 읽기 페이지는 조건에 대해 다시 검사됩니다.


아, 그것이 비트 맵 을 채우는 의미 입니다.
St.Antario

@ St.Antario 설명 할 그래픽을 추가했습니다
Craig Ringer

비트 맵 스캔에 대해 한 가지 더 설명하겠습니다. 우리는 힙 페이지에 대한 1 : 1 비트 맵이 있으며 비트 맵의 ​​비트 인덱스로 힙 페이지를 결정할 수 있다고 말했습니다. 관계는 디스크의 페이지를 순차적이 아닌 순서 (클러스터되지 않은 순서로)로 포함 할 수 있으므로 비트 맵으로 오프셋하여 페이지의 주소를 확인할 수있는 방법이 명확하지 않습니다. 필자 는 플래너가 주어진 관계에 대해 오프셋으로 페이지 주소를 계산하는 방법을 알고 있다고 가정 합니다 . 그게 사실입니까?
St.Antario

1
따라서 드라이브에있는 모든 페이지를 넣어야합니다. 또한 relation의 데이터가 둘 이상의 드라이브에 분산 될 수 있으므로 ( 관계형 페이지의 선형 순서 를 상상 하기 어렵 기 때문에) 다음 페이지의 실제 오프셋을 결정하기가 어렵습니다. "오프셋"이란 드라이브의 물리적 위치에 해당하는 실제 물리적 오프셋을 의미한다고 생각하기 때문입니다.
St.Antario

2
PostgreSQL은 드라이브에 대해 거의 신경 쓰지 않습니다. 그것은 단지에 대한 관심 파일 상의 파일 시스템 . 관계 의 논리 파일은 선형적이고 연속적이며 비트 맵이 끝난 것입니다. 파일에 여러 범위가있을 수 있지만 연속적으로 추가되는 것처럼 처리되고 비트 맵이 모두 해당됩니다. 잘못된 추상화 수준을보고 있습니다. 참고로, 비트 맵 인덱스 스캔의 비트 맵은 플래너가 계산하지 않으며 btree 인덱스 액세스 방법의 일부이며 플래너보다 실행자와 더 관련이 있습니다.
Craig Ringer

3

PostgreSQL의 비트 맵 스캔에 대한 자세한 설명은 내 블로그 게시물 https://rajeevrastogi.blogspot.in/2018/02/bitmap-scan-in-postgresql.html?showComment=1518410565792#c4647352762092142586 를 참조하십시오 .

비트 맵 스캔에 대한 전반적인 빠른 기능 개요 :

  1. 비트 맵 힙 스캔은 비트 맵 인덱스 스캔에서 튜플을 요청합니다.

  2. 비트 맵 인덱스 스캔은 일반적인 인덱스 스캔에서와 거의 동일한 방식으로 조건에 따라 인덱스를 스캔합니다. 그러나 힙 데이터에 해당하는 TID (페이지 번호 및 그 내부의 오프셋으로 구성됨)를 반환하는 대신 비트 맵에 해당 TID를 추가합니다. 간단히 이해하기 위해이 비트 맵에는 모든 페이지의 해시 (페이지 번호를 기준으로 해시)가 포함되어 있고 각 페이지 항목에는 해당 페이지 내의 모든 오프셋 배열이 포함되어 있습니다.

  3. 그런 다음 비트 맵 힙 스캔은 비트 맵을 읽고 저장된 페이지 번호 및 오프셋에 해당하는 힙 데이터를 가져옵니다. 그런 다음 가시성, 자격 등을 확인하고 이러한 모든 확인 결과에 따라 튜플을 반환합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.