From 9220b361070ae138183da495235160aff55931b0 Mon Sep 17 00:00:00 2001 From: amit Date: Mon, 15 Oct 2018 10:59:24 +0900 Subject: [PATCH v20 3/4] Teach planner to only process unpruned partitions This adds a bitmapset field live_parts to RelOptInfo and stores the partition indexes of non-dummy partitions in it, meaning it contains indexes of only those partitions that have a non-NULL RelOptInfo present in its parent's RelOptInfo's part_rels array. This speeds up processing partitioned table's partitions compared to going through the whole part_rels array in a number of places. --- src/backend/optimizer/path/joinrels.c | 3 +++ src/backend/optimizer/plan/planner.c | 18 +++++++++--------- src/backend/optimizer/util/inherit.c | 1 + src/backend/optimizer/util/relnode.c | 3 +++ src/backend/partitioning/partprune.c | 18 +++++------------- src/include/nodes/pathnodes.h | 4 ++++ 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 6f77d2a0f4..fdbf7689ed 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -1452,6 +1452,9 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, populate_joinrel_with_paths(root, child_rel1, child_rel2, child_joinrel, child_sjinfo, child_restrictlist); + if (!IS_DUMMY_REL(child_joinrel)) + joinrel->live_parts = bms_add_member(joinrel->live_parts, + cnt_parts); } } diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 9f3cfd7f63..fc86abe12d 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -6847,7 +6847,9 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, List *live_children = NIL; /* Adjust each partition. */ - for (partition_idx = 0; partition_idx < rel->nparts; partition_idx++) + partition_idx = -1; + while ((partition_idx = bms_next_member(rel->live_parts, + partition_idx)) >= 0) { RelOptInfo *child_rel = rel->part_rels[partition_idx]; ListCell *lc; @@ -6855,9 +6857,7 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, int nappinfos; List *child_scanjoin_targets = NIL; - /* Skip processing pruned partitions. */ - if (child_rel == NULL) - continue; + Assert(child_rel != NULL); /* Translate scan/join targets for this child. */ appinfos = find_appinfos_by_relids(root, child_rel->relids, @@ -6938,7 +6938,6 @@ create_partitionwise_grouping_paths(PlannerInfo *root, PartitionwiseAggregateType patype, GroupPathExtraData *extra) { - int nparts = input_rel->nparts; int cnt_parts; List *grouped_live_children = NIL; List *partially_grouped_live_children = NIL; @@ -6950,7 +6949,9 @@ create_partitionwise_grouping_paths(PlannerInfo *root, partially_grouped_rel != NULL); /* Add paths for partitionwise aggregation/grouping. */ - for (cnt_parts = 0; cnt_parts < nparts; cnt_parts++) + cnt_parts = -1; + while ((cnt_parts = bms_next_member(input_rel->live_parts, + cnt_parts)) >= 0) { RelOptInfo *child_input_rel = input_rel->part_rels[cnt_parts]; PathTarget *child_target = copy_pathtarget(target); @@ -6960,9 +6961,8 @@ create_partitionwise_grouping_paths(PlannerInfo *root, RelOptInfo *child_grouped_rel; RelOptInfo *child_partially_grouped_rel; - /* Skip processing pruned partitions. */ - if (child_input_rel == NULL) - continue; + /* A live partition must have a RelOptInfo. */ + Assert(child_input_rel != NULL); /* Input child rel must have a path */ Assert(child_input_rel->pathlist != NIL); diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index 579286e54c..b014bb4633 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -365,6 +365,7 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte, /* Perform pruning. */ partindexes = prune_append_rel_partitions(parentrel); + parentrel->live_parts = partindexes; /* Must expand PlannerInfo arrays before we can add children. */ if (bms_num_members(partindexes) > 0) diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 09b1b8075a..cfb8077575 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -1734,6 +1734,9 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, joinrel->partexprs[cnt] = partexpr; joinrel->nullable_partexprs[cnt] = nullable_partexpr; } + + /* Partitions will be added by try_partitionwise_join. */ + joinrel->live_parts = NULL; } /* diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index 472a6cd331..babb7d3406 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -438,29 +438,21 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, memset(subplan_map, -1, nparts * sizeof(int)); subpart_map = (int *) palloc(nparts * sizeof(int)); memset(subpart_map, -1, nparts * sizeof(int)); - present_parts = NULL; + present_parts = bms_copy(subpart->live_parts); - for (i = 0; i < nparts; i++) + i = -1; + while ((i = bms_next_member(present_parts, i)) >= 0) { RelOptInfo *partrel = subpart->part_rels[i]; int subplanidx; int subpartidx; - /* Skip processing pruned partitions. */ - if (partrel == NULL) - continue; - + Assert(partrel != NULL); subplan_map[i] = subplanidx = relid_subplan_map[partrel->relid] - 1; subpart_map[i] = subpartidx = relid_subpart_map[partrel->relid] - 1; + /* Record finding this subplan */ if (subplanidx >= 0) - { - present_parts = bms_add_member(present_parts, i); - - /* Record finding this subplan */ subplansfound = bms_add_member(subplansfound, subplanidx); - } - else if (subpartidx >= 0) - present_parts = bms_add_member(present_parts, i); } pinfo = makeNode(PartitionedRelPruneInfo); diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 1d36bda039..2571c17f65 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -739,6 +739,10 @@ typedef struct RelOptInfo Oid *part_oids; /* partition OIDs */ struct RelOptInfo **part_rels; /* Array of RelOptInfos of partitions, * stored in the same order of bounds */ + Bitmapset *live_parts; /* Indexes into part_rels of the non-NULL + * RelOptInfos of unpruned partitions; exists + * to avoid having to iterate over the entire + * part_rels array to filter NULL entries. */ List **partexprs; /* Non-nullable partition key expressions. */ List **nullable_partexprs; /* Nullable partition key expressions. */ List *partitioned_child_rels; /* List of RT indexes. */ -- 2.11.0