Skip to content

Commit 475dbd0

Browse files
committed
Track a Bitmapset of non-pruned partitions in RelOptInfo
For partitioned tables with large numbers of partitions where queries are able to prune all but a very small number of partitions, the time spent in the planner looping over RelOptInfo.part_rels checking for non-NULL RelOptInfos could become a large portion of the overall planning time. Here we add a Bitmapset that records the non-pruned partitions. This allows us to more efficiently skip the pruned partitions by looping over the Bitmapset. This will cause a very slight slow down in cases where no or not many partitions could be pruned, however, those cases are already slow to plan anyway and the overhead of looping over the Bitmapset would be unmeasurable when compared with the other tasks such as path creation for a large number of partitions. Reviewed-by: Amit Langote, Zhihong Yu Discussion: https://postgr.es/m/CAApHDvqnPx6JnUuPwaf5ao38zczrAb9mxt9gj4U1EKFfd4AqLA@mail.gmail.com
1 parent a5cb4f9 commit 475dbd0

File tree

7 files changed

+31
-17
lines changed

7 files changed

+31
-17
lines changed

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,6 +2386,7 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node)
23862386
WRITE_BOOL_FIELD(consider_partitionwise_join);
23872387
WRITE_BITMAPSET_FIELD(top_parent_relids);
23882388
WRITE_BOOL_FIELD(partbounds_merged);
2389+
WRITE_BITMAPSET_FIELD(live_parts);
23892390
WRITE_BITMAPSET_FIELD(all_partrels);
23902391
}
23912392

src/backend/optimizer/path/joinrels.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,7 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
15391539
child_sjinfo,
15401540
child_sjinfo->jointype);
15411541
joinrel->part_rels[cnt_parts] = child_joinrel;
1542+
joinrel->live_parts = bms_add_member(joinrel->live_parts, cnt_parts);
15421543
joinrel->all_partrels = bms_add_members(joinrel->all_partrels,
15431544
child_joinrel->relids);
15441545
}

src/backend/optimizer/plan/planner.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6989,19 +6989,22 @@ apply_scanjoin_target_to_paths(PlannerInfo *root,
69896989
if (rel_is_partitioned)
69906990
{
69916991
List *live_children = NIL;
6992-
int partition_idx;
6992+
int i;
69936993

69946994
/* Adjust each partition. */
6995-
for (partition_idx = 0; partition_idx < rel->nparts; partition_idx++)
6995+
i = -1;
6996+
while ((i = bms_next_member(rel->live_parts, i)) >= 0)
69966997
{
6997-
RelOptInfo *child_rel = rel->part_rels[partition_idx];
6998+
RelOptInfo *child_rel = rel->part_rels[i];
69986999
AppendRelInfo **appinfos;
69997000
int nappinfos;
70007001
List *child_scanjoin_targets = NIL;
70017002
ListCell *lc;
70027003

7003-
/* Pruned or dummy children can be ignored. */
7004-
if (child_rel == NULL || IS_DUMMY_REL(child_rel))
7004+
Assert(child_rel != NULL);
7005+
7006+
/* Dummy children can be ignored. */
7007+
if (IS_DUMMY_REL(child_rel))
70057008
continue;
70067009

70077010
/* Translate scan/join targets for this child. */
@@ -7082,32 +7085,36 @@ create_partitionwise_grouping_paths(PlannerInfo *root,
70827085
PartitionwiseAggregateType patype,
70837086
GroupPathExtraData *extra)
70847087
{
7085-
int nparts = input_rel->nparts;
7086-
int cnt_parts;
70877088
List *grouped_live_children = NIL;
70887089
List *partially_grouped_live_children = NIL;
70897090
PathTarget *target = grouped_rel->reltarget;
70907091
bool partial_grouping_valid = true;
7092+
int i;
70917093

70927094
Assert(patype != PARTITIONWISE_AGGREGATE_NONE);
70937095
Assert(patype != PARTITIONWISE_AGGREGATE_PARTIAL ||
70947096
partially_grouped_rel != NULL);
70957097

70967098
/* Add paths for partitionwise aggregation/grouping. */
7097-
for (cnt_parts = 0; cnt_parts < nparts; cnt_parts++)
7099+
i = -1;
7100+
while ((i = bms_next_member(input_rel->live_parts, i)) >= 0)
70987101
{
7099-
RelOptInfo *child_input_rel = input_rel->part_rels[cnt_parts];
7100-
PathTarget *child_target = copy_pathtarget(target);
7102+
RelOptInfo *child_input_rel = input_rel->part_rels[i];
7103+
PathTarget *child_target;
71017104
AppendRelInfo **appinfos;
71027105
int nappinfos;
71037106
GroupPathExtraData child_extra;
71047107
RelOptInfo *child_grouped_rel;
71057108
RelOptInfo *child_partially_grouped_rel;
71067109

7107-
/* Pruned or dummy children can be ignored. */
7108-
if (child_input_rel == NULL || IS_DUMMY_REL(child_input_rel))
7110+
Assert(child_input_rel != NULL);
7111+
7112+
/* Dummy children can be ignored. */
7113+
if (IS_DUMMY_REL(child_input_rel))
71097114
continue;
71107115

7116+
child_target = copy_pathtarget(target);
7117+
71117118
/*
71127119
* Copy the given "extra" structure as is and then override the
71137120
* members specific to this child.

src/backend/optimizer/util/inherit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo,
348348
* that survive pruning. Below, we will initialize child objects for the
349349
* surviving partitions.
350350
*/
351-
live_parts = prune_append_rel_partitions(relinfo);
351+
relinfo->live_parts = live_parts = prune_append_rel_partitions(relinfo);
352352

353353
/* Expand simple_rel_array and friends to hold child objects. */
354354
num_live_parts = bms_num_members(live_parts);

src/backend/optimizer/util/relnode.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
255255
rel->partbounds_merged = false;
256256
rel->partition_qual = NIL;
257257
rel->part_rels = NULL;
258+
rel->live_parts = NULL;
258259
rel->all_partrels = NULL;
259260
rel->partexprs = NULL;
260261
rel->nullable_partexprs = NULL;
@@ -669,6 +670,7 @@ build_join_rel(PlannerInfo *root,
669670
joinrel->partbounds_merged = false;
670671
joinrel->partition_qual = NIL;
671672
joinrel->part_rels = NULL;
673+
joinrel->live_parts = NULL;
672674
joinrel->all_partrels = NULL;
673675
joinrel->partexprs = NULL;
674676
joinrel->nullable_partexprs = NULL;
@@ -847,6 +849,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
847849
joinrel->partbounds_merged = false;
848850
joinrel->partition_qual = NIL;
849851
joinrel->part_rels = NULL;
852+
joinrel->live_parts = NULL;
850853
joinrel->all_partrels = NULL;
851854
joinrel->partexprs = NULL;
852855
joinrel->nullable_partexprs = NULL;

src/backend/partitioning/partprune.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -654,15 +654,14 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
654654
relid_map = (Oid *) palloc0(nparts * sizeof(Oid));
655655
present_parts = NULL;
656656

657-
for (i = 0; i < nparts; i++)
657+
i = -1;
658+
while ((i = bms_next_member(subpart->live_parts, i)) >= 0)
658659
{
659660
RelOptInfo *partrel = subpart->part_rels[i];
660661
int subplanidx;
661662
int subpartidx;
662663

663-
/* Skip processing pruned partitions. */
664-
if (partrel == NULL)
665-
continue;
664+
Assert(partrel != NULL);
666665

667666
subplan_map[i] = subplanidx = relid_subplan_map[partrel->relid] - 1;
668667
subpart_map[i] = subpartidx = relid_subpart_map[partrel->relid] - 1;

src/include/nodes/pathnodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,9 @@ typedef struct RelOptInfo
762762
List *partition_qual; /* Partition constraint, if not the root */
763763
struct RelOptInfo **part_rels; /* Array of RelOptInfos of partitions,
764764
* stored in the same order as bounds */
765+
Bitmapset *live_parts; /* Bitmap with members acting as indexes into
766+
* the part_rels[] array to indicate which
767+
* partitions survived partition pruning. */
765768
Relids all_partrels; /* Relids set of all partition relids */
766769
List **partexprs; /* Non-nullable partition key expressions */
767770
List **nullable_partexprs; /* Nullable partition key expressions */

0 commit comments

Comments
 (0)