diff -rupN postgresql-8.4.0-orig/src/backend/access/heap/heapam.c postgresql-8.4.0-ra/src/backend/access/heap/heapam.c --- postgresql-8.4.0-orig/src/backend/access/heap/heapam.c 2009-06-11 16:48:53.000000000 +0200 +++ postgresql-8.4.0-ra/src/backend/access/heap/heapam.c 2009-08-08 10:41:15.000000000 +0200 @@ -135,6 +135,8 @@ initscan(HeapScanDesc scan, ScanKey key, { if (scan->rs_strategy == NULL) scan->rs_strategy = GetAccessStrategy(BAS_BULKREAD); + + scan->rs_readahead_pages = 4096; /* TODO: GUC ? or maybe put it in AccessStrategy ? */ } else { @@ -766,6 +768,12 @@ heapgettup_pagemode(HeapScanDesc scan, if (page == 0) page = scan->rs_nblocks; page--; + + /* + * do some extra readahead (really needed for compressed files) + */ + if( scan->rs_readahead_pages && !finished ) + PrefetchBuffer( scan->rs_rd, MAIN_FORKNUM, page - scan->rs_readahead_pages + ((page >= scan->rs_readahead_pages) ? 0 : scan->rs_nblocks)); } else { @@ -788,6 +796,13 @@ heapgettup_pagemode(HeapScanDesc scan, */ if (scan->rs_syncscan) ss_report_location(scan->rs_rd, page); + + /* + * do some extra readahead (really needed for compressed files) + */ + + if( scan->rs_readahead_pages && !finished && (page & 4096)) + PrefetchBuffer( scan->rs_rd, MAIN_FORKNUM, (page + scan->rs_readahead_pages) % scan->rs_nblocks ); } /* @@ -1209,6 +1224,7 @@ heap_beginscan_internal(Relation relatio scan->rs_strategy = NULL; /* set in initscan */ scan->rs_allow_strat = allow_strat; scan->rs_allow_sync = allow_sync; + scan->rs_readahead_pages = 0; /* * we can use page-at-a-time mode if it's an MVCC-safe snapshot diff -rupN postgresql-8.4.0-orig/src/include/access/relscan.h postgresql-8.4.0-ra/src/include/access/relscan.h --- postgresql-8.4.0-orig/src/include/access/relscan.h 2009-01-01 18:23:56.000000000 +0100 +++ postgresql-8.4.0-ra/src/include/access/relscan.h 2009-08-08 09:44:38.000000000 +0200 @@ -35,6 +35,7 @@ typedef struct HeapScanDescData BlockNumber rs_startblock; /* block # to start at */ BufferAccessStrategy rs_strategy; /* access strategy for reads */ bool rs_syncscan; /* report location to syncscan logic? */ + int rs_readahead_pages; /* if non-zero, issue a Prefetch to get a page rs_readahead_pages ahead of current page */ /* scan current state */ bool rs_inited; /* false = scan not init'd yet */