postgres.git / summary / log / commit / refs

commit    4c910f3bbe92aa4e84ff15fa27b4de2da0d7ae50
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Tue Mar 10 22:36:10 2026 +0000

    bloom: Optimize bitmap scan path with streaming read
    
    This commit replaces the per-page buffer read look in blgetbitmap() with
    a reading stream, to improve scan efficiency, particularly useful for
    large bloom indexes.  Some benchmarking with a large number of rows has
    shown a very nice improvement in terms of runtime and IO read reduction
    with test cases up to 10M rows for a bloom index scan.
    
    For the io_uring method, The author has reported a 3x in runtime with
    io_uring while I was at close to a 7x.  For the worker method with 3
    workers, the author has reported better numbers than myself in runtime,
    with the reduction in IO stats being appealing for all the cases
    measured.
    
    Author: Xuneng Zhou <xunengzhou@gmail.com>
    Reviewed-by: Michael Paquier <michael@paquier.xyz>
    Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
    Discussion: https://postgr.es/m/CABPTF7VrqfbcDXqGrdLQ2xaQ=K0RzExNuw6U_GGqzSJu32wfdQ@mail.gmail.com


contrib/bloom/blscan.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c index 0535d45f2d8..1a0e42021ec 100644 --- a/contrib/bloom/blscan.c +++ b/contrib/bloom/blscan.c @@ -18,6 +18,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "storage/bufmgr.h" +#include "storage/read_stream.h" /* * Begin scan of bloom index. @@ -76,11 +77,13 @@ int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) { int64 ntids = 0; - BlockNumber blkno = BLOOM_HEAD_BLKNO, + BlockNumber blkno, npages; int i; BufferAccessStrategy bas; BloomScanOpaque so = (BloomScanOpaque) scan->opaque; + BlockRangeReadStreamPrivate p; + ReadStream *stream; if (so->sign == NULL) { @@ -120,14 +123,29 @@ blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) if (scan->instrument) scan->instrument->nsearches++; + /* Scan all blocks except the metapage using streaming reads */ + p.current_blocknum = BLOOM_HEAD_BLKNO; + p.last_exclusive = npages; + + /* + * It is safe to use batchmode as block_range_read_stream_cb takes no + * locks. + */ + stream = read_stream_begin_relation(READ_STREAM_FULL | + READ_STREAM_USE_BATCHING, + bas, + scan->indexRelation, + MAIN_FORKNUM, + block_range_read_stream_cb, + &p, + 0); + for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++) { Buffer buffer; Page page; - buffer = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM, - blkno, RBM_NORMAL, bas); - + buffer = read_stream_next_buffer(stream, NULL); LockBuffer(buffer, BUFFER_LOCK_SHARE); page = BufferGetPage(buffer); @@ -163,6 +181,9 @@ blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) UnlockReleaseBuffer(buffer); CHECK_FOR_INTERRUPTS(); } + + Assert(read_stream_next_buffer(stream, NULL) == InvalidBuffer); + read_stream_end(stream); FreeAccessStrategy(bas); return ntids; [parent: 4c7362c55366]