Skip to content

Commit 25fe8b5

Browse files
committed
Add a 'parallel_degree' reloption.
The code that estimates what parallel degree should be uesd for the scan of a relation is currently rather stupid, so add a parallel_degree reloption that can be used to override the planner's rather limited judgement. Julien Rouhaud, reviewed by David Rowley, James Sewell, Amit Kapila, and me. Some further hacking by me.
1 parent b0b64f6 commit 25fe8b5

File tree

8 files changed

+86
-23
lines changed

8 files changed

+86
-23
lines changed

doc/src/sgml/ref/create_table.sgml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,19 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
908908
</listitem>
909909
</varlistentry>
910910

911+
<varlistentry>
912+
<term><literal>parallel_degree</> (<type>integer</>)</term>
913+
<listitem>
914+
<para>
915+
The parallel degree for a table is the number of workers that should
916+
be used to assist a parallel scan of that table. If not set, the
917+
system will determine a value based on the relation size. The actual
918+
number of workers chosen by the planner may be less, for example due to
919+
the setting of <xref linkend="guc-max-parallel-degree">.
920+
</para>
921+
</listitem>
922+
</varlistentry>
923+
911924
<varlistentry>
912925
<term><literal>autovacuum_enabled</>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</>)</term>
913926
<listitem>

src/backend/access/common/reloptions.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "commands/tablespace.h"
2727
#include "commands/view.h"
2828
#include "nodes/makefuncs.h"
29+
#include "postmaster/postmaster.h"
2930
#include "utils/array.h"
3031
#include "utils/attoptcache.h"
3132
#include "utils/builtins.h"
@@ -267,6 +268,15 @@ static relopt_int intRelOpts[] =
267268
0, 0, 0
268269
#endif
269270
},
271+
{
272+
{
273+
"parallel_degree",
274+
"Number of parallel processes that can be used per executor node for this relation.",
275+
RELOPT_KIND_HEAP,
276+
AccessExclusiveLock
277+
},
278+
-1, 0, MAX_BACKENDS
279+
},
270280

271281
/* list terminator */
272282
{{NULL}}
@@ -1251,8 +1261,7 @@ fillRelOptions(void *rdopts, Size basesize,
12511261

12521262

12531263
/*
1254-
* Option parser for anything that uses StdRdOptions (i.e. fillfactor and
1255-
* autovacuum)
1264+
* Option parser for anything that uses StdRdOptions.
12561265
*/
12571266
bytea *
12581267
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
@@ -1291,7 +1300,9 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
12911300
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
12921301
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_scale_factor)},
12931302
{"user_catalog_table", RELOPT_TYPE_BOOL,
1294-
offsetof(StdRdOptions, user_catalog_table)}
1303+
offsetof(StdRdOptions, user_catalog_table)},
1304+
{"parallel_degree", RELOPT_TYPE_INT,
1305+
offsetof(StdRdOptions, parallel_degree)}
12951306
};
12961307

12971308
options = parseRelOptions(reloptions, validate, kind, &numoptions);

src/backend/optimizer/path/allpaths.c

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -659,31 +659,55 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
659659
static void
660660
create_parallel_paths(PlannerInfo *root, RelOptInfo *rel)
661661
{
662-
int parallel_threshold = 1000;
663-
int parallel_degree = 1;
662+
int parallel_degree = 1;
664663

665664
/*
666-
* If this relation is too small to be worth a parallel scan, just return
667-
* without doing anything ... unless it's an inheritance child. In that case,
668-
* we want to generate a parallel path here anyway. It might not be worthwhile
669-
* just for this relation, but when combined with all of its inheritance siblings
670-
* it may well pay off.
665+
* If the user has set the parallel_degree reloption, we decide what to do
666+
* based on the value of that option. Otherwise, we estimate a value.
671667
*/
672-
if (rel->pages < parallel_threshold && rel->reloptkind == RELOPT_BASEREL)
673-
return;
668+
if (rel->rel_parallel_degree != -1)
669+
{
670+
/*
671+
* If parallel_degree = 0 is set for this relation, bail out. The
672+
* user does not want a parallel path for this relation.
673+
*/
674+
if (rel->rel_parallel_degree == 0)
675+
return;
674676

675-
/*
676-
* Limit the degree of parallelism logarithmically based on the size of the
677-
* relation. This probably needs to be a good deal more sophisticated, but we
678-
* need something here for now.
679-
*/
680-
while (rel->pages > parallel_threshold * 3 &&
681-
parallel_degree < max_parallel_degree)
677+
/*
678+
* Use the table parallel_degree, but don't go further than
679+
* max_parallel_degree.
680+
*/
681+
parallel_degree = Min(rel->rel_parallel_degree, max_parallel_degree);
682+
}
683+
else
682684
{
683-
parallel_degree++;
684-
parallel_threshold *= 3;
685-
if (parallel_threshold >= PG_INT32_MAX / 3)
686-
break;
685+
int parallel_threshold = 1000;
686+
687+
/*
688+
* If this relation is too small to be worth a parallel scan, just
689+
* return without doing anything ... unless it's an inheritance child.
690+
* In that case, we want to generate a parallel path here anyway. It
691+
* might not be worthwhile just for this relation, but when combined
692+
* with all of its inheritance siblings it may well pay off.
693+
*/
694+
if (rel->pages < parallel_threshold &&
695+
rel->reloptkind == RELOPT_BASEREL)
696+
return;
697+
698+
/*
699+
* Limit the degree of parallelism logarithmically based on the size
700+
* of the relation. This probably needs to be a good deal more
701+
* sophisticated, but we need something here for now.
702+
*/
703+
while (rel->pages > parallel_threshold * 3 &&
704+
parallel_degree < max_parallel_degree)
705+
{
706+
parallel_degree++;
707+
parallel_threshold *= 3;
708+
if (parallel_threshold >= PG_INT32_MAX / 3)
709+
break;
710+
}
687711
}
688712

689713
/* Add an unordered partial path based on a parallel sequential scan. */

src/backend/optimizer/util/plancat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
133133
estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
134134
&rel->pages, &rel->tuples, &rel->allvisfrac);
135135

136+
/* Retrive the parallel_degree reloption, if set. */
137+
rel->rel_parallel_degree = RelationGetParallelDegree(relation, -1);
138+
136139
/*
137140
* Make list of indexes. Ignore indexes on system catalogs if told to.
138141
* Don't bother with indexes for an inheritance parent, either.

src/backend/optimizer/util/relnode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind)
107107
rel->consider_startup = (root->tuple_fraction > 0);
108108
rel->consider_param_startup = false; /* might get changed later */
109109
rel->consider_parallel = false; /* might get changed later */
110+
rel->rel_parallel_degree = -1; /* set up in GetRelationInfo */
110111
rel->reltarget = create_empty_pathtarget();
111112
rel->pathlist = NIL;
112113
rel->ppilist = NIL;

src/bin/psql/tab-complete.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,7 @@ psql_completion(const char *text, int start, int end)
17831783
"autovacuum_vacuum_scale_factor",
17841784
"autovacuum_vacuum_threshold",
17851785
"fillfactor",
1786+
"parallel_degree",
17861787
"log_autovacuum_min_duration",
17871788
"toast.autovacuum_enabled",
17881789
"toast.autovacuum_freeze_max_age",

src/include/nodes/relation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ typedef struct RelOptInfo
522522
double allvisfrac;
523523
PlannerInfo *subroot; /* if subquery */
524524
List *subplan_params; /* if subquery */
525+
int rel_parallel_degree; /* wanted number of parallel workers */
525526

526527
/* Information about foreign tables and foreign joins */
527528
Oid serverid; /* identifies server for the table or join */

src/include/utils/rel.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ typedef struct StdRdOptions
206206
AutoVacOpts autovacuum; /* autovacuum-related options */
207207
bool user_catalog_table; /* use as an additional catalog
208208
* relation */
209+
int parallel_degree; /* max number of parallel workers */
209210
} StdRdOptions;
210211

211212
#define HEAP_MIN_FILLFACTOR 10
@@ -242,6 +243,14 @@ typedef struct StdRdOptions
242243
((relation)->rd_options ? \
243244
((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
244245

246+
/*
247+
* RelationGetParallelDegree
248+
* Returns the relation's parallel_degree. Note multiple eval of argument!
249+
*/
250+
#define RelationGetParallelDegree(relation, defaultpd) \
251+
((relation)->rd_options ? \
252+
((StdRdOptions *) (relation)->rd_options)->parallel_degree : (defaultpd))
253+
245254

246255
/*
247256
* ViewOptions

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy