Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc6fc50c

Browse files
committed
Use pre-fetching for ANALYZE
When we have posix_fadvise() available, we can improve the performanceof an ANALYZE by quite a bit by using it to inform the kernel of theblocks that we're going to be asking for. Similar to bitmap indexscans, the number of buffers pre-fetched is based off of themaintenance_io_concurrency setting (for the particular tablespace or,if not set, globally, via get_tablespace_maintenance_io_concurrency()).Reviewed-By: Heikki Linnakangas, Tomas VondraDiscussion:https://www.postgresql.org/message-id/VI1PR0701MB69603A433348EDCF783C6ECBF6EF0%40VI1PR0701MB6960.eurprd07.prod.outlook.com
1 parent94d13d4 commitc6fc50c

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

‎src/backend/commands/analyze.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include"utils/pg_rusage.h"
6464
#include"utils/sampling.h"
6565
#include"utils/sortsupport.h"
66+
#include"utils/spccache.h"
6667
#include"utils/syscache.h"
6768
#include"utils/timestamp.h"
6869

@@ -1127,6 +1128,7 @@ acquire_sample_rows(Relation onerel, int elevel,
11271128
doubleliverows=0;/* # live rows seen */
11281129
doubledeadrows=0;/* # dead rows seen */
11291130
doublerowstoskip=-1;/* -1 means not set yet */
1131+
longrandseed;/* Seed for block sampler(s) */
11301132
BlockNumbertotalblocks;
11311133
TransactionIdOldestXmin;
11321134
BlockSamplerDatabs;
@@ -1135,6 +1137,10 @@ acquire_sample_rows(Relation onerel, int elevel,
11351137
TableScanDescscan;
11361138
BlockNumbernblocks;
11371139
BlockNumberblksdone=0;
1140+
#ifdefUSE_PREFETCH
1141+
intprefetch_maximum=0;/* blocks to prefetch if enabled */
1142+
BlockSamplerDataprefetch_bs;
1143+
#endif
11381144

11391145
Assert(targrows>0);
11401146

@@ -1144,7 +1150,15 @@ acquire_sample_rows(Relation onerel, int elevel,
11441150
OldestXmin=GetOldestNonRemovableTransactionId(onerel);
11451151

11461152
/* Prepare for sampling block numbers */
1147-
nblocks=BlockSampler_Init(&bs,totalblocks,targrows,random());
1153+
randseed=random();
1154+
nblocks=BlockSampler_Init(&bs,totalblocks,targrows,randseed);
1155+
1156+
#ifdefUSE_PREFETCH
1157+
prefetch_maximum=get_tablespace_io_concurrency(onerel->rd_rel->reltablespace);
1158+
/* Create another BlockSampler, using the same seed, for prefetching */
1159+
if (prefetch_maximum)
1160+
(void)BlockSampler_Init(&prefetch_bs,totalblocks,targrows,randseed);
1161+
#endif
11481162

11491163
/* Report sampling block numbers */
11501164
pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_TOTAL,
@@ -1156,14 +1170,69 @@ acquire_sample_rows(Relation onerel, int elevel,
11561170
scan=table_beginscan_analyze(onerel);
11571171
slot=table_slot_create(onerel,NULL);
11581172

1173+
#ifdefUSE_PREFETCH
1174+
1175+
/*
1176+
* If we are doing prefetching, then go ahead and tell the kernel about
1177+
* the first set of pages we are going to want. This also moves our
1178+
* iterator out ahead of the main one being used, where we will keep it so
1179+
* that we're always pre-fetching out prefetch_maximum number of blocks
1180+
* ahead.
1181+
*/
1182+
if (prefetch_maximum)
1183+
{
1184+
for (inti=0;i<prefetch_maximum;i++)
1185+
{
1186+
BlockNumberprefetch_block;
1187+
1188+
if (!BlockSampler_HasMore(&prefetch_bs))
1189+
break;
1190+
1191+
prefetch_block=BlockSampler_Next(&prefetch_bs);
1192+
PrefetchBuffer(scan->rs_rd,MAIN_FORKNUM,prefetch_block);
1193+
}
1194+
}
1195+
#endif
1196+
11591197
/* Outer loop over blocks to sample */
11601198
while (BlockSampler_HasMore(&bs))
11611199
{
1200+
boolblock_accepted;
11621201
BlockNumbertargblock=BlockSampler_Next(&bs);
1202+
#ifdefUSE_PREFETCH
1203+
BlockNumberprefetch_targblock=InvalidBlockNumber;
1204+
1205+
/*
1206+
* Make sure that every time the main BlockSampler is moved forward
1207+
* that our prefetch BlockSampler also gets moved forward, so that we
1208+
* always stay out ahead.
1209+
*/
1210+
if (prefetch_maximum&&BlockSampler_HasMore(&prefetch_bs))
1211+
prefetch_targblock=BlockSampler_Next(&prefetch_bs);
1212+
#endif
11631213

11641214
vacuum_delay_point();
11651215

1166-
if (!table_scan_analyze_next_block(scan,targblock,vac_strategy))
1216+
block_accepted=table_scan_analyze_next_block(scan,targblock,vac_strategy);
1217+
1218+
#ifdefUSE_PREFETCH
1219+
1220+
/*
1221+
* When pre-fetching, after we get a block, tell the kernel about the
1222+
* next one we will want, if there's any left.
1223+
*
1224+
* We want to do this even if the table_scan_analyze_next_block() call
1225+
* above decides against analyzing the block it picked.
1226+
*/
1227+
if (prefetch_maximum&&prefetch_targblock!=InvalidBlockNumber)
1228+
PrefetchBuffer(scan->rs_rd,MAIN_FORKNUM,prefetch_targblock);
1229+
#endif
1230+
1231+
/*
1232+
* Don't analyze if table_scan_analyze_next_block() indicated this
1233+
* block is unsuitable for analyzing.
1234+
*/
1235+
if (!block_accepted)
11671236
continue;
11681237

11691238
while (table_scan_analyze_next_tuple(scan,OldestXmin,&liverows,&deadrows,slot))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp