비트 맵 인덱스 스캔을 사용하는 쿼리 계획의“Concheck Cond :”줄


21

이것은 의견에서 이전 질문으로의 분리입니다.

PostgreSQL 9.4를 사용하면의 Recheck Cond:쿼리 계획 출력에서 ​​비트 맵 인덱스 스캔 후 항상 줄 이있는 것 같습니다 EXPLAIN.

EXPLAIN참조 된 질문 의 출력 에서와 같이 :

->  Bitmap Heap Scan on table_three  (cost=2446.92..19686.74 rows=8159 width=7)
      Recheck Cond: (("timestamp" > (now() - '30 days'::interval)) AND (client_id > 0))
      ->  BitmapAnd  (cost=2446.92..2446.92 rows=8159 width=0)
            ->  Bitmap Index Scan on table_one_timestamp_idx  (cost=0.00..1040.00 rows=79941 width=0)
                  Index Cond: ("timestamp" > (now() - '30 days'::interval))
            ->  Bitmap Index Scan on fki_table_three_client_id  (cost=0.00..1406.05 rows=107978 width=0)
                  Index Cond: (client_id > 0)

또는 EXPLAIN ANALYZE간단하고 거대한 테이블 의 출력에서 (거의 거의 없음 work_mem) :

EXPLAIN ANALYZE SELECT * FROM aa WHERE a BETWEEN 100000 AND 200000;
Bitmap Heap Scan on aa  (cost=107.68..4818.05 rows=5000 width=4) (actual time=27.629..213.606 rows=100001 loops=1)
  Recheck Cond: ((a >= 100000) AND (a <= 200000))
  Rows Removed by Index Recheck: 758222
  Heap Blocks: exact=693 lossy=3732
  ->  Bitmap Index Scan on aai  (cost=0.00..106.43 rows=5000 width=0) (actual time=27.265..27.265 rows=100001 loops=1)
        Index Cond: ((a >= 100000) AND (a <= 200000))

비트 맵 인덱스 스캔 후 인덱스 조건을 다시 확인해야합니까? 출력
에서 무엇을 더 배울 수 EXPLAIN있습니까?

답변:


17

@Chris가 참조 된 질문에 올바르게 주석을 달았 듯이 :

약간의 조사는 재확인 조건이 항상에 인쇄됨을 나타내지 EXPLAIN만 실제로 work_mem비트 맵이 손실 될 정도로 작은 경우에만 수행됩니다 . 생각? http://www.postgresql.org/message-id/464F3C5D.2000700@enterprisedb.com

이것이 사실이며 핵심 개발자 인 Heikki Linnakangas는 일류 소스이지만 게시물은 2007 년으로 거슬러 올라갑니다 (Postgres 8.2). 여기입니다 포스트 그레스 9.4에 대한 자세한 설명과 마이클 Paquier에 의해 블로그 게시물 의 출력을, EXPLAIN ANALYZE더 많은 정보 향상되었습니다가.

Recheck Cond:라인은 항상 비트 맵 인덱스 스캔을 위해있다. 기본의 결과는 EXPLAIN우리에게 더 많은 것을 말하지 않을 것입니다. EXPLAIN ANALYZE질문의 두 번째 인용문에서 볼 수 있듯이 추가 정보를 얻습니다 .

Heap Blocks: exact=693 lossy=3732

총 4425 개의 데이터 페이지 (블록)에서 693은 튜플을 정확히 저장 (튜플 포인터 포함) 한 반면 다른 3732 페이지는 비트 맵에서 손실되었습니다 (데이터 페이지 만). work_mem인덱스 스캔으로 빌드 된 전체 비트 맵을 정확하게 (무손실) 저장할 수있을만큼 크지 않은 경우에 발생합니다 .

비트 맵은 페치 할 페이지 만 기억하고 페이지의 정확한 튜플은 기억하지 않기 때문에 인덱스 공유는 손실 공유에서 페이지를 다시 확인해야합니다. 페이지의 모든 튜플이 색인 조건을 반드시 통과 할 필요 없으며 실제로 조건을 다시 확인해야합니다.

이것은 새로운 추가 사항이 논의 된 pgsql 해커스레드입니다 . 저자 인 Etsuro Fujita는work_mem 손실 비트 맵 항목을 피하고 조건 재확인 을 피하기 위해 최소값 을 계산하는 방법에 대한 공식제공합니다 . 비트 맵 스캔이 여러 개인 복잡한 경우에는 계산이 신뢰할 수 없으므로에서 실제 숫자를 출력하는 데 사용되지 않았습니다 EXPLAIN. 간단한 사례의 추정치로 여전히 사용할 수 있습니다.

추가 라인 BUFFERS:

또한 BUFFERS옵션으로 실행하면 다음 EXPLAIN (ANALYZE, BUFFERS) ...과 같이 다른 줄이 추가됩니다.

Buffers: shared hit=279 read=79

캐시 ( shared hit=279) 에서 읽은 기본 테이블 및 인덱스의 양과 디스크에서 가져와야 하는 양을 나타냅니다 read=79. 쿼리를 반복하면 첫 번째 호출 이후에 모든 것이 이제 캐시되므로 너무 큰 쿼리에서는 "읽기"부분이 사라집니다. 첫 번째 호출은 이미 캐시 된 양을 알려줍니다. 후속 호출은 캐시가 현재 처리 할 수있는 양을 보여줍니다.

더 많은 옵션이 있습니다. 옵션 에 대한 매뉴얼 BUFFERS:

구체적으로, 적중, 읽기, 더티 및 기록 된 공유 블록 수, 적중, 읽기, 더티 및 기록 된 로컬 블록 수 및 읽고 쓴 임시 블록 수를 포함하십시오.

더 읽으십시오.
다음은 소스 코드 의 출력 옵션 목록입니다 .


10

어윈, 이것은 이전의 코멘트 스레드에서 우리의 토론 이었으므로 조금 더 찌르기로 결정했습니다 ...

합리적인 크기의 테이블에서 매우 간단한 쿼리가 있습니다. 나는 일반적으로 충분 work_mem하지만이 경우에는 명령을 사용했다.

SET work_mem = 64;

아주 작게 설정 work_mem하고

SET work_mem = default;

등을 work_mem내 쿼리에 맞게 충분히 크게 설정했습니다 .

설명 및 재확인 조건

따라서 다음과 EXPLAIN같이 쿼리를 실행 하면

EXPLAIN 
SELECT * FROM olap.reading_facts
WHERE meter < 20;

나는 낮고 높은 결과를 얻었습니다 work_mem.

낮은 work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

높은 work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

긴 이야기 짧은에 대한 EXPLAIN예상대로 만 쿼리 계획은 다시 검사 조건이 가능하다는 것을 나타내지 만 실제로 계산 될 경우 우리는 알 수 없습니다.

설명 분석 및 재확인 조건

우리가 포함되면 ANALYZE쿼리에서 텔 우리는 더 우리가 알아야 할 사항에 대해 발생합니다.

낮은 work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Rows Removed by Index Recheck: 86727
  Heap Blocks: exact=598 lossy=836
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
        Index Cond: (meter < 20)

높은 work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Heap Blocks: exact=1434
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
        Index Cond: (meter < 20)

다시 한 번, 예상 한대로 포함하면 ANALYZE매우 중요한 정보 가 나타납니다. 낮은 work_mem경우 인덱스 재확인으로 행이 제거되고 lossy힙 블록 이 있음을 알 수 있습니다 .

결론? (또는 그 부족)

불행하게도, 그것은 보이는 EXPLAIN그 자체 것은 충분하지 행 아이디의 일부 비트 맵 힙 스캔 동안 유지 페이지에 찬성 삭제되기 때문에 인덱스 재 점검이 실제로 필요합니다 여부를 알 수 있습니다.

EXPLAIN ANALYZE중간 길이의 쿼리로 문제를 진단하는 데는 사용하는 것이 좋지만 쿼리를 완료하는 데 시간이 오래 걸리는 경우 EXPLAIN ANALYZE비트 맵 인덱스가 불충분하여 손실로 변환된다는 것을 발견하기 위해 실행 work_mem하는 것은 여전히 ​​어려운 제약입니다. EXPLAIN테이블 통계에서이 발생 가능성을 추정 할 수있는 방법이 있었으면 합니다.

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