Recheck Cond: Dòng trong kế hoạch truy vấn với quét chỉ mục bitmap


21

Đây là phần phụ từ các bình luận cho câu hỏi trước:

Sử dụng PostgreQuery 9.4, dường như luôn có một Recheck Cond:dòng sau khi quét chỉ mục bitmap trong đầu ra của kế hoạch truy vấn EXPLAIN.

Giống như trong EXPLAINđầu ra của câu hỏi được tham chiếu:

->  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)

Hoặc trong đầu ra của EXPLAIN ANALYZEmột bảng đơn giản, khổng lồ (với rất ít 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))

Điều đó có nghĩa là các điều kiện chỉ mục phải được kiểm tra lần thứ hai sau khi quét chỉ mục bitmap?
Chúng ta có thể học được gì khác từ EXPLAINđầu ra?

Câu trả lời:


17

Như @Chris đã nhận xét chính xác về câu hỏi được tham chiếu :

một cuộc điều tra nhỏ dường như chỉ ra rằng điều kiện kiểm tra lại luôn được in trong EXPLAIN, nhưng thực tế chỉ được thực hiện khi work_memđủ nhỏ để bitmap trở nên mất mát. Suy nghĩ? http://www.postgresql.org/message-id/464F3C5D.2000700@enterprisedb.com

Mặc dù điều này hoàn toàn đúng và nhà phát triển cốt lõi Heikki Linnakangas là nguồn cấp đầu tiên, bài đăng có từ năm 2007 (Postgres 8.2). Dưới đây là một bài đăng trên blog của Michael Paquier với lời giải thích chi tiết cho Postgres 9.4 , trong đó đầu ra của EXPLAIN ANALYZEđã được cải thiện với nhiều thông tin hơn.

Các Recheck Cond:dòng là luôn luôn ở đó cho lần quét chỉ mục bitmap. Đầu ra của cơ bản EXPLAINsẽ không cho chúng tôi biết thêm. Chúng tôi nhận được thông tin bổ sung từ EXPLAIN ANALYZEnhư có thể được nhìn thấy trong trích dẫn thứ hai trong câu hỏi:

Heap Blocks: exact=693 lossy=3732

Từ tổng số 4425 trang dữ liệu (khối), 693 bộ dữ liệu được lưu trữ chính xác (bao gồm cả bộ con trỏ tuple), trong khi 3732 trang khác bị mất (chỉ trang dữ liệu) trong bitmap. Điều đó xảy ra khi work_memkhông đủ lớn để lưu trữ toàn bộ bitmap được xây dựng từ quét chỉ mục chính xác (lossless).

Điều kiện chỉ mục phải được kiểm tra lại cho các trang từ chia sẻ mất mát, vì bitmap chỉ nhớ các trang cần tìm nạp và không phải là các bộ dữ liệu chính xác trên trang. Không phải tất cả các bộ dữ liệu trên trang sẽ nhất thiết phải vượt qua các điều kiện chỉ mục, thực sự cần thiết kiểm tra lại điều kiện.

Đây là chủ đề về tin tặc pssql nơi bổ sung mới đã được thảo luận . Tác giả Etsuro Fujita cung cấp một công thức về cách tính mức tối thiểuwork_mem để tránh các mục bitmap mất mát và kiểm tra lại điều kiện tiếp theo. Tính toán không đáng tin cậy cho các trường hợp phức tạp với nhiều lần quét bitmap, do đó, nó không được sử dụng để xuất số thực tế từ đó EXPLAIN. Nó vẫn có thể phục vụ như một ước tính cho các trường hợp đơn giản.

Dòng bổ sung BUFFERS:

Ngoài ra, khi chạy với BUFFERStùy chọn: EXPLAIN (ANALYZE, BUFFERS) ...một dòng khác được thêm vào như:

Buffers: shared hit=279 read=79

Điều này cho biết bao nhiêu bảng bên dưới (và chỉ mục) đã được đọc từ bộ đệm ( shared hit=279) và bao nhiêu phải được tìm nạp từ đĩa ( read=79). Nếu bạn lặp lại truy vấn, phần "đọc" thường biến mất cho các truy vấn không quá lớn, vì mọi thứ đều được lưu trong bộ nhớ cache sau cuộc gọi đầu tiên. Cuộc gọi đầu tiên cho bạn biết bao nhiêu đã được lưu trữ. Các cuộc gọi tiếp theo cho thấy bộ nhớ cache của bạn có thể xử lý được bao nhiêu (hiện tại).

Có nhiều lựa chọn hơn. Hướng dẫn về BUFFERStùy chọn:

Cụ thể, bao gồm số khối chia sẻ đánh, đọc, làm bẩn và viết, số khối cục bộ đánh, đọc, làm bẩn và viết, và số khối tạm thời đọc và viết.

Đọc tiếp, có nhiều hơn.
Dưới đây là danh sách các tùy chọn đầu ra trong mã nguồn .


10

Erwin, vì đây là cuộc thảo luận của chúng tôi trong chuỗi nhận xét từ trước, tôi quyết định chọc vào nó thêm một chút ...

Tôi có một truy vấn rất đơn giản từ một bảng có kích thước hợp lý. Tôi thường có đủ work_mem, nhưng trong trường hợp này tôi đã sử dụng các lệnh

SET work_mem = 64;

để đặt rất nhỏ work_mem

SET work_mem = default;

để đặt work_memlưng của tôi đủ lớn cho truy vấn của tôi.

GIẢI THÍCH & Kiểm tra lại điều kiện

Vì vậy, chạy truy vấn của tôi chỉ EXPLAINvới

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

Tôi đã thu được kết quả cho cả thấp và cao work_mem:

Thấp 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)

Cao 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)

Câu chuyện dài, cho EXPLAIN chỉ, như dự kiến, kế hoạch truy vấn chỉ ra rằng điều kiện Kiểm tra lại là có thể, nhưng chúng ta không thể biết liệu thực sự sẽ được tính toán hay không.

GIẢI THÍCH ANALYZE & Kiểm tra lại điều kiện

Khi chúng tôi đưa ANALYZEvào truy vấn, kết quả sẽ cho chúng tôi biết thêm về những gì chúng tôi cần biết.

Thấp 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)

Cao 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)

Một lần nữa, như mong đợi, việc đưa vào ANALYZEtiết lộ cho chúng tôi một số thông tin rất quan trọng. Trong work_memtrường hợp thấp , chúng tôi thấy rằng có các hàng bị xóa bởi kiểm tra lại chỉ mục và chúng tôi có lossycác khối heap.

Phần kết luận? (hoạc thiếu điều đó)

Thật không may, có vẻ như EXPLAINbản thân nó không đủ để biết liệu kiểm tra lại chỉ số có thực sự cần thiết hay không bởi vì một số id của hàng bị bỏ qua để giữ lại các trang trong quá trình quét heap bitmap.

Sử dụng EXPLAIN ANALYZElà tốt để chẩn đoán các vấn đề với các truy vấn có độ dài vừa phải, nhưng trong trường hợp truy vấn mất một thời gian rất dài để hoàn thành, sau đó chạy EXPLAIN ANALYZEđể phát hiện ra rằng chỉ số bitmap của bạn đang chuyển thành mất do không đủ work_memvẫn là một ràng buộc khó khăn. Tôi ước có một cách để EXPLAINước tính khả năng xảy ra sự cố này từ bảng thống kê.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.