OSDN Git Service

Support PostgreSQL 10 beta 1 step 2/2
authorKyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Tue, 6 Jun 2017 10:56:41 +0000 (19:56 +0900)
committerKyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Tue, 6 Jun 2017 11:07:39 +0000 (20:07 +0900)
Changed the logic to tweak parallel execution paths so that it handles
more wider (parallel index scans or gather merge, specifically) range
of parallel paths.

expected/ut-W.out
pg_hint_plan.c
sql/ut-W.sql

index c7b9402..bb74d27 100644 (file)
@@ -494,7 +494,7 @@ error hint:
                      ->  Parallel Seq Scan on p1_c3_c2
 (25 rows)
 
--- seqscan doesn't harm parallelism
+-- Parallel sequential scan
 /*+Parallel(p1 8 hard) SeqScan(p1) */
 EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
 LOG:  pg_hint_plan:
@@ -534,7 +534,7 @@ error hint:
                      ->  Seq Scan on p2_c3_c2
 (25 rows)
 
--- Index partial scan is not handled yet.
+-- Parallel index scan
 /*+Parallel(p1 8 hard) IndexScan(p1) */
 EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
 LOG:  pg_hint_plan:
@@ -545,32 +545,34 @@ not used hint:
 duplication hint:
 error hint:
 
-                       QUERY PLAN                       
---------------------------------------------------------
- Hash Join
-   Hash Cond: (p1.id = p2.id)
-   ->  Append
-         ->  Index Scan using p1_pkey on p1
-         ->  Index Scan using p1_c1_pkey on p1_c1
-         ->  Index Scan using p1_c2_pkey on p1_c2
-         ->  Index Scan using p1_c3_pkey on p1_c3
-         ->  Index Scan using p1_c4_pkey on p1_c4
-         ->  Index Scan using p1_c1_c1_pkey on p1_c1_c1
-         ->  Index Scan using p1_c1_c2_pkey on p1_c1_c2
-         ->  Index Scan using p1_c3_c1_pkey on p1_c3_c1
-         ->  Index Scan using p1_c3_c2_pkey on p1_c3_c2
-   ->  Hash
+                              QUERY PLAN                               
+-----------------------------------------------------------------------
+ Gather
+   Workers Planned: 8
+   ->  Hash Join
+         Hash Cond: (p1.id = p2.id)
          ->  Append
-               ->  Seq Scan on p2
-               ->  Seq Scan on p2_c1
-               ->  Seq Scan on p2_c2
-               ->  Seq Scan on p2_c3
-               ->  Seq Scan on p2_c4
-               ->  Seq Scan on p2_c1_c1
-               ->  Seq Scan on p2_c1_c2
-               ->  Seq Scan on p2_c3_c1
-               ->  Seq Scan on p2_c3_c2
-(23 rows)
+               ->  Parallel Index Scan using p1_pkey on p1
+               ->  Parallel Index Scan using p1_c1_pkey on p1_c1
+               ->  Parallel Index Scan using p1_c2_pkey on p1_c2
+               ->  Parallel Index Scan using p1_c3_pkey on p1_c3
+               ->  Parallel Index Scan using p1_c4_pkey on p1_c4
+               ->  Parallel Index Scan using p1_c1_c1_pkey on p1_c1_c1
+               ->  Parallel Index Scan using p1_c1_c2_pkey on p1_c1_c2
+               ->  Parallel Index Scan using p1_c3_c1_pkey on p1_c3_c1
+               ->  Parallel Index Scan using p1_c3_c2_pkey on p1_c3_c2
+         ->  Hash
+               ->  Append
+                     ->  Seq Scan on p2
+                     ->  Seq Scan on p2_c1
+                     ->  Seq Scan on p2_c2
+                     ->  Seq Scan on p2_c3
+                     ->  Seq Scan on p2_c4
+                     ->  Seq Scan on p2_c1_c1
+                     ->  Seq Scan on p2_c1_c2
+                     ->  Seq Scan on p2_c3_c1
+                     ->  Seq Scan on p2_c3_c2
+(25 rows)
 
 -- This hint doesn't turn on parallel, so the Parallel hint is ignored
 set max_parallel_workers_per_gather TO 0;
index 26db50d..505ffdf 100644 (file)
@@ -4433,50 +4433,24 @@ pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel,
                return;
 
        /* Here, we regenerate paths with the current hint restriction */
-
-       if (found_hints & HINT_BM_SCAN_METHOD)
+       if (found_hints & HINT_BM_SCAN_METHOD || found_hints & HINT_BM_PARALLEL)
        {
-               /*
-                * With scan hints, we regenerate paths for this relation from the
-                * first under the restricion.
-                */
+               /* Just discard all the paths considered so far */
                list_free_deep(rel->pathlist);
                rel->pathlist = NIL;
 
-               set_plain_rel_pathlist(root, rel, rte);
-       }
-
-       if (found_hints & HINT_BM_PARALLEL)
-       {
-               Assert (phint);
-
-               /* the partial_pathlist may be for different parameters, discard it */
-               if (rel->partial_pathlist)
+               /* Remove all the partial paths if Parallel hint is specfied */
+               if ((found_hints & HINT_BM_PARALLEL) && rel->partial_pathlist)
                {
                        list_free_deep(rel->partial_pathlist);
                        rel->partial_pathlist = NIL;
                }
 
-               /* also remove gather path */
-               if (rel->pathlist)
-               {
-                       ListCell *cell, *prev = NULL, *next;
-
-                       for (cell = list_head(rel->pathlist) ; cell; cell = next)
-                       {
-                               Path *path = (Path *) lfirst(cell);
-
-                               next = lnext(cell);
-                               if (IsA(path, GatherPath))
-                                       rel->pathlist = list_delete_cell(rel->pathlist,
-                                                                                                        cell, prev);
-                               else
-                                       prev = cell;
-                       }
-               }
+               /* Regenerate paths with the current enforcement */
+               set_plain_rel_pathlist(root, rel, rte);
 
-               /* then generate new paths if needed */
-               if (phint->nworkers > 0)
+               /* Additional work to enforce parallel query execution */
+               if (phint && phint->nworkers > 0)
                {
                        /* Lower the priorities of non-parallel paths */
                        foreach (l, rel->pathlist)
@@ -4490,15 +4464,6 @@ pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel,
                                }
                        }
 
-                       /*
-                        * generate partial paths with enforcement, this is affected by
-                        * scan method enforcement. Specifically, the cost of this partial
-                        * seqscan path will be disabled_cost if seqscan is inhibited by
-                        * hint or GUC parameters.
-                        */
-                       Assert (rel->partial_pathlist == NIL);
-                       create_plain_partial_paths(root, rel);
-
                        /* enforce number of workers if requested */
                        if (phint->force_parallel)
                        {
index d72c763..199b607 100644 (file)
@@ -98,11 +98,11 @@ EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
 /*+Parallel(p1 8 hard) IndexScan(p2) */
 EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
 
--- seqscan doesn't harm parallelism
+-- Parallel sequential scan
 /*+Parallel(p1 8 hard) SeqScan(p1) */
 EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
 
--- Index partial scan is not handled yet.
+-- Parallel index scan
 /*+Parallel(p1 8 hard) IndexScan(p1) */
 EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;