Factor out logic for computing number of parallel workers.
authorRobert Haas <[email protected]>
Wed, 18 Jan 2017 18:50:35 +0000 (13:50 -0500)
committerRobert Haas <[email protected]>
Wed, 18 Jan 2017 18:54:45 +0000 (13:54 -0500)
Forthcoming patches to allow other types of parallel scans will
need this logic, or something like it.

Dilip Kumar

src/backend/optimizer/path/allpaths.c

index da68d0d61fc42d6fc849c24914fa96d35a640299..96ca7d3bb0748da465b4452d2d821a23d37c98fe 100644 (file)
@@ -126,6 +126,7 @@ static void subquery_push_qual(Query *subquery,
 static void recurse_push_qual(Node *setOp, Query *topquery,
                  RangeTblEntry *rte, Index rti, Node *qual);
 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)
 {
    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 (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);
+   parallel_workers = compute_parallel_worker(rel, rel->pages);
 
    /* If any limit was set to zero, the user doesn't want a parallel scan. */
    if (parallel_workers <= 0)
@@ -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
  *****************************************************************************/