diff options
Diffstat (limited to 'src/backend/commands/analyze.c')
-rw-r--r-- | src/backend/commands/analyze.c | 85 |
1 files changed, 25 insertions, 60 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 2fb39f3ede1..da27a13a3f0 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -1103,6 +1103,20 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr) } /* + * Read stream callback returning the next BlockNumber as chosen by the + * BlockSampling algorithm. + */ +static BlockNumber +block_sampling_read_stream_next(ReadStream *stream, + void *callback_private_data, + void *per_buffer_data) +{ + BlockSamplerData *bs = callback_private_data; + + return BlockSampler_HasMore(bs) ? BlockSampler_Next(bs) : InvalidBlockNumber; +} + +/* * acquire_sample_rows -- acquire a random sample of rows from the heap * * Selected rows are returned in the caller-allocated array rows[], which @@ -1154,10 +1168,7 @@ acquire_sample_rows(Relation onerel, int elevel, TableScanDesc scan; BlockNumber nblocks; BlockNumber blksdone = 0; -#ifdef USE_PREFETCH - int prefetch_maximum = 0; /* blocks to prefetch if enabled */ - BlockSamplerData prefetch_bs; -#endif + ReadStream *stream; Assert(targrows > 0); @@ -1170,13 +1181,6 @@ acquire_sample_rows(Relation onerel, int elevel, randseed = pg_prng_uint32(&pg_global_prng_state); nblocks = BlockSampler_Init(&bs, totalblocks, targrows, randseed); -#ifdef USE_PREFETCH - prefetch_maximum = get_tablespace_maintenance_io_concurrency(onerel->rd_rel->reltablespace); - /* Create another BlockSampler, using the same seed, for prefetching */ - if (prefetch_maximum) - (void) BlockSampler_Init(&prefetch_bs, totalblocks, targrows, randseed); -#endif - /* Report sampling block numbers */ pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_TOTAL, nblocks); @@ -1187,60 +1191,19 @@ acquire_sample_rows(Relation onerel, int elevel, scan = heap_beginscan(onerel, NULL, 0, NULL, NULL, SO_TYPE_ANALYZE); slot = table_slot_create(onerel, NULL); -#ifdef USE_PREFETCH - - /* - * If we are doing prefetching, then go ahead and tell the kernel about - * the first set of pages we are going to want. This also moves our - * iterator out ahead of the main one being used, where we will keep it so - * that we're always pre-fetching out prefetch_maximum number of blocks - * ahead. - */ - if (prefetch_maximum) - { - for (int i = 0; i < prefetch_maximum; i++) - { - BlockNumber prefetch_block; - - if (!BlockSampler_HasMore(&prefetch_bs)) - break; - - prefetch_block = BlockSampler_Next(&prefetch_bs); - PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, prefetch_block); - } - } -#endif + stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE, + vac_strategy, + scan->rs_rd, + MAIN_FORKNUM, + block_sampling_read_stream_next, + &bs, + 0); /* Outer loop over blocks to sample */ - while (BlockSampler_HasMore(&bs)) + while (heapam_scan_analyze_next_block(scan, stream)) { - BlockNumber targblock = BlockSampler_Next(&bs); -#ifdef USE_PREFETCH - BlockNumber prefetch_targblock = InvalidBlockNumber; - - /* - * Make sure that every time the main BlockSampler is moved forward - * that our prefetch BlockSampler also gets moved forward, so that we - * always stay out ahead. - */ - if (prefetch_maximum && BlockSampler_HasMore(&prefetch_bs)) - prefetch_targblock = BlockSampler_Next(&prefetch_bs); -#endif - vacuum_delay_point(); - heapam_scan_analyze_next_block(scan, targblock, vac_strategy); - -#ifdef USE_PREFETCH - - /* - * When pre-fetching, after we get a block, tell the kernel about the - * next one we will want, if there's any left. - */ - if (prefetch_maximum && prefetch_targblock != InvalidBlockNumber) - PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, prefetch_targblock); -#endif - while (heapam_scan_analyze_next_tuple(scan, OldestXmin, &liverows, &deadrows, slot)) { /* @@ -1290,6 +1253,8 @@ acquire_sample_rows(Relation onerel, int elevel, ++blksdone); } + read_stream_end(stream); + ExecDropSingleTupleTableSlot(slot); heap_endscan(scan); |