From 096c645d7c8d06df3a4e6a8aa7fc4edd1c0a3755 Mon Sep 17 00:00:00 2001 From: "tender.wang" Date: Thu, 7 Sep 2023 17:55:04 +0800 Subject: [PATCH v2] Parallel seq scan should consider materila inner path in nestloop case. --- src/backend/optimizer/path/joinpath.c | 19 +++++++++++++++ src/test/regress/expected/select_parallel.out | 24 +++++++++++++++++++ src/test/regress/sql/select_parallel.sql | 9 +++++++ 3 files changed, 52 insertions(+) diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 821d282497..87111ad643 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -2004,10 +2004,25 @@ consider_parallel_nestloop(PlannerInfo *root, { JoinType save_jointype = jointype; ListCell *lc1; + Path *matpath = NULL; + Path *inner_cheapest_total = innerrel->cheapest_total_path; if (jointype == JOIN_UNIQUE_INNER) jointype = JOIN_INNER; + /* + * Consider materializing the cheapest inner path, unless we're + * doing JOIN_UNIQUE_INNER or enable_material is off or the subpath + * is parallel unsafe or the path in question materializes its output anyway. + */ + if (save_jointype != JOIN_UNIQUE_INNER && + enable_material && + inner_cheapest_total != NULL && + inner_cheapest_total->parallel_safe && + !ExecMaterializesOutput(inner_cheapest_total->pathtype)) + matpath = (Path *) + create_material_path(innerrel, inner_cheapest_total); + foreach(lc1, outerrel->partial_pathlist) { Path *outerpath = (Path *) lfirst(lc1); @@ -2064,6 +2079,10 @@ consider_parallel_nestloop(PlannerInfo *root, try_partial_nestloop_path(root, joinrel, outerpath, mpath, pathkeys, jointype, extra); } + /* Also consider materialized form of the cheapest inner path */ + if (matpath != NULL && matpath->parallel_safe) + try_partial_nestloop_path(root, joinrel, outerpath, matpath, + pathkeys, jointype, extra); } } diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index d88353d496..5b9f5c58cc 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -844,6 +844,30 @@ select * from (12 rows) reset enable_material; +-- test materialized form of the cheapest inner path +set min_parallel_table_scan_size = '512kB'; +explain(costs off) +select count(*) from tenk1, int4_tbl where tenk1.two < int4_tbl.f1; + QUERY PLAN +------------------------------------------------------------ + Finalize Aggregate + -> Gather + Workers Planned: 4 + -> Partial Aggregate + -> Nested Loop + Join Filter: (tenk1.two < int4_tbl.f1) + -> Parallel Seq Scan on tenk1 + -> Materialize + -> Seq Scan on int4_tbl +(9 rows) + +select count(*) from tenk1, int4_tbl where tenk1.two < int4_tbl.f1; + count +------- + 20000 +(1 row) + +set min_parallel_table_scan_size = 0; reset enable_hashagg; -- check parallelized int8 aggregate (bug #14897) explain (costs off) diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index 80c914dc02..0afae0c750 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -312,6 +312,15 @@ select * from reset enable_material; +-- test materialized form of the cheapest inner path +set min_parallel_table_scan_size = '512kB'; + +explain(costs off) +select count(*) from tenk1, int4_tbl where tenk1.two < int4_tbl.f1; + +select count(*) from tenk1, int4_tbl where tenk1.two < int4_tbl.f1; + +set min_parallel_table_scan_size = 0; reset enable_hashagg; -- check parallelized int8 aggregate (bug #14897) -- 2.25.1