Commit 716c7d4b authored by Robert Haas's avatar Robert Haas

Factor out logic for computing number of parallel workers.

Forthcoming patches to allow other types of parallel scans will
need this logic, or something like it.

Dilip Kumar
parent 0333a734
...@@ -126,6 +126,7 @@ static void subquery_push_qual(Query *subquery, ...@@ -126,6 +126,7 @@ static void subquery_push_qual(Query *subquery,
static void recurse_push_qual(Node *setOp, Query *topquery, static void recurse_push_qual(Node *setOp, Query *topquery,
RangeTblEntry *rte, Index rti, Node *qual); RangeTblEntry *rte, Index rti, Node *qual);
static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel); static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel);
static int compute_parallel_worker(RelOptInfo *rel, BlockNumber pages);
/* /*
...@@ -678,49 +679,7 @@ create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel) ...@@ -678,49 +679,7 @@ create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
{ {
int parallel_workers; int parallel_workers;
/* parallel_workers = compute_parallel_worker(rel, rel->pages);
* If the user has set the parallel_workers reloption, use that; otherwise
* select a default number of workers.
*/
if (rel->rel_parallel_workers != -1)
parallel_workers = rel->rel_parallel_workers;
else
{
int parallel_threshold;
/*
* If this relation is too small to be worth a parallel scan, just
* return without doing anything ... unless it's an inheritance child.
* In that case, we want to generate a parallel path here anyway. It
* might not be worthwhile just for this relation, but when combined
* with all of its inheritance siblings it may well pay off.
*/
if (rel->pages < (BlockNumber) min_parallel_relation_size &&
rel->reloptkind == RELOPT_BASEREL)
return;
/*
* Select the number of workers based on the log of the size of the
* relation. This probably needs to be a good deal more
* sophisticated, but we need something here for now. Note that the
* upper limit of the min_parallel_relation_size GUC is chosen to
* prevent overflow here.
*/
parallel_workers = 1;
parallel_threshold = Max(min_parallel_relation_size, 1);
while (rel->pages >= (BlockNumber) (parallel_threshold * 3))
{
parallel_workers++;
parallel_threshold *= 3;
if (parallel_threshold > INT_MAX / 3)
break; /* avoid overflow */
}
}
/*
* In no case use more than max_parallel_workers_per_gather workers.
*/
parallel_workers = Min(parallel_workers, max_parallel_workers_per_gather);
/* If any limit was set to zero, the user doesn't want a parallel scan. */ /* If any limit was set to zero, the user doesn't want a parallel scan. */
if (parallel_workers <= 0) if (parallel_workers <= 0)
...@@ -2908,6 +2867,64 @@ remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel) ...@@ -2908,6 +2867,64 @@ remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel)
} }
} }
/*
* Compute the number of parallel workers that should be used to scan a
* relation. "pages" is the number of pages from the relation that we
* expect to scan.
*/
static int
compute_parallel_worker(RelOptInfo *rel, BlockNumber pages)
{
int parallel_workers;
/*
* If the user has set the parallel_workers reloption, use that; otherwise
* select a default number of workers.
*/
if (rel->rel_parallel_workers != -1)
parallel_workers = rel->rel_parallel_workers;
else
{
int parallel_threshold;
/*
* If this relation is too small to be worth a parallel scan, just
* return without doing anything ... unless it's an inheritance child.
* In that case, we want to generate a parallel path here anyway. It
* might not be worthwhile just for this relation, but when combined
* with all of its inheritance siblings it may well pay off.
*/
if (pages < (BlockNumber) min_parallel_relation_size &&
rel->reloptkind == RELOPT_BASEREL)
return 0;
/*
* Select the number of workers based on the log of the size of the
* relation. This probably needs to be a good deal more
* sophisticated, but we need something here for now. Note that the
* upper limit of the min_parallel_relation_size GUC is chosen to
* prevent overflow here.
*/
parallel_workers = 1;
parallel_threshold = Max(min_parallel_relation_size, 1);
while (pages >= (BlockNumber) (parallel_threshold * 3))
{
parallel_workers++;
parallel_threshold *= 3;
if (parallel_threshold > INT_MAX / 3)
break; /* avoid overflow */
}
}
/*
* In no case use more than max_parallel_workers_per_gather workers.
*/
parallel_workers = Min(parallel_workers, max_parallel_workers_per_gather);
return parallel_workers;
}
/***************************************************************************** /*****************************************************************************
* DEBUG SUPPORT * DEBUG SUPPORT
*****************************************************************************/ *****************************************************************************/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment