On 16/03/2016 18:42, Robert Haas wrote: > On Wed, Mar 16, 2016 at 1:23 PM, Julien Rouhaud > <julien.rouh...@dalibo.com> wrote: >> On 16/03/2016 17:55, Robert Haas wrote: >>> On Wed, Mar 16, 2016 at 12:47 PM, Julien Rouhaud >>> <julien.rouh...@dalibo.com> wrote: >>>> Something like a "min_parallel_degree" then ? >>> >>> Why not just parallel_degree without any prefix? As in, when scanning >>> this table in parallel, the reloption suggests using N workers. >>> >> >> Agreed. >> >> PFA v2 that implements that. > > I think create_parallel_paths shouldn't actually run the loop if the > reloption is specified; it should just adopt the specified value (or > max_parallel_degree, whichever is less). Right now, you have it doing > the work to compute the default value but then overriding it. >
Oh ugly mistake. Fixed. > Also, I think parallel_degree should be down in the section that says > /* information about a base rel (not set for join rels!) */ and I > think it should be called something like rel_parallel_degree, to make > it more clear that it's a value set on the relation level. > You're right, fixed. > Let's leave out the parallel_threshold stuff for now. > attached v3 drops the GUC part. -- Julien Rouhaud http://dalibo.com - http://dalibo.org
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index cd234db..80e1f09 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -909,6 +909,17 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI </varlistentry> <varlistentry> + <term><literal>parallel_degree</> (<type>integer</>)</term> + <listitem> + <para> + Number of workers wanted for this table. The number of worker will be + limited according to the <xref linkend="gux-max-parallel-degree"> + parameter. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><literal>autovacuum_enabled</>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</>)</term> <listitem> <para> diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index ea0755a..68bb133 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -267,6 +267,15 @@ static relopt_int intRelOpts[] = 0, 0, 0 #endif }, + { + { + "parallel_degree", + "Number of parallel processes per executor node wanted for this relation.", + RELOPT_KIND_HEAP, + AccessExclusiveLock + }, + -1, 1, INT_MAX + }, /* list terminator */ {{NULL}} @@ -1291,7 +1300,9 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) {"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL, offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_scale_factor)}, {"user_catalog_table", RELOPT_TYPE_BOOL, - offsetof(StdRdOptions, user_catalog_table)} + offsetof(StdRdOptions, user_catalog_table)}, + {"parallel_degree", RELOPT_TYPE_INT, + offsetof(StdRdOptions, parallel_degree)} }; options = parseRelOptions(reloptions, validate, kind, &numoptions); diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 4f60b85..617872d 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -673,17 +673,26 @@ create_parallel_paths(PlannerInfo *root, RelOptInfo *rel) return; /* - * Limit the degree of parallelism logarithmically based on the size of the - * relation. This probably needs to be a good deal more sophisticated, but we - * need something here for now. + * Use the table parallel_degree if specified, but don't go further than + * max_parallel_degree */ - while (rel->pages > parallel_threshold * 3 && - parallel_degree < max_parallel_degree) + if (rel->rel_parallel_degree > 0) + parallel_degree = Min(rel->rel_parallel_degree, max_parallel_degree); + else { - parallel_degree++; - parallel_threshold *= 3; - if (parallel_threshold >= PG_INT32_MAX / 3) - break; + /* + * Limit the degree of parallelism logarithmically based on the size of the + * relation. This probably needs to be a good deal more sophisticated, but we + * need something here for now. + */ + while (rel->pages > parallel_threshold * 3 && + parallel_degree < max_parallel_degree) + { + parallel_degree++; + parallel_threshold *= 3; + if (parallel_threshold >= PG_INT32_MAX / 3) + break; + } } /* Add an unordered partial path based on a parallel sequential scan. */ diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index ad715bb..709d192 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -128,6 +128,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, estimate_rel_size(relation, rel->attr_widths - rel->min_attr, &rel->pages, &rel->tuples, &rel->allvisfrac); + /* Setup the per-relation parallel_degree */ + rel->rel_parallel_degree = RelationGetParallelDegree(relation, -1); /* * Make list of indexes. Ignore indexes on system catalogs if told to. * Don't bother with indexes for an inheritance parent, either. diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 20e4bf7..af4f2fa 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -107,6 +107,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) rel->consider_startup = (root->tuple_fraction > 0); rel->consider_param_startup = false; /* might get changed later */ rel->consider_parallel = false; /* might get changed later */ + rel->rel_parallel_degree = -1; /* set up in GetRelationInfo */ rel->reltarget = create_empty_pathtarget(); rel->pathlist = NIL; rel->ppilist = NIL; diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 6a81416..e8b00ca 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1782,6 +1782,7 @@ psql_completion(const char *text, int start, int end) "autovacuum_vacuum_scale_factor", "autovacuum_vacuum_threshold", "fillfactor", + "parallel_degree", "log_autovacuum_min_duration", "toast.autovacuum_enabled", "toast.autovacuum_freeze_max_age", diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 5032696..580c56e 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -521,6 +521,7 @@ typedef struct RelOptInfo double allvisfrac; PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ + int rel_parallel_degree; /* wanted number of parallel workers */ /* Information about foreign tables and foreign joins */ Oid serverid; /* identifies server for the table or join */ diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index f2bebf2..8bf5dbc 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -203,6 +203,7 @@ typedef struct StdRdOptions AutoVacOpts autovacuum; /* autovacuum-related options */ bool user_catalog_table; /* use as an additional catalog * relation */ + int parallel_degree; /* max number of parallel worker */ } StdRdOptions; #define HEAP_MIN_FILLFACTOR 10 @@ -217,6 +218,14 @@ typedef struct StdRdOptions ((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff)) /* + * RelationGetMaxParallelDegree + * Returns the relation's parallel_degree. Note multiple eval of argument! + */ +#define RelationGetParallelDegree(relation, defaultmpd) \ + ((relation)->rd_options ? \ + ((StdRdOptions *) (relation)->rd_options)->parallel_degree : (defaultmpd)) + +/* * RelationGetTargetPageUsage * Returns the relation's desired space usage per page in bytes. */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers