Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb10e3bb

Browse files
author
Etsuro Fujita
committed
Postpone generating tlists and EC members for inheritance dummy children.
Previously, in set_append_rel_size(), we generated tlists and EC membersfor dummy children for possible use by partition-wise join, even ifpartition-wise join was disabled or the top parent was not a partitionedtable, but adding such EC members causes noticeable planning speeddegradation for queries with certain kinds of join quals like"(foo.x + bar.y) = constant" where foo and bar are partitioned tables incases where there are lots of dummy children, as the EC members listsgrow huge, especially for the ECs derived from such join quals, whichmakes the search for the parent EC members in add_child_rel_equivalences()very time-consuming. Postpone the work until such children are actuallyinvolved in a partition-wise join.Reported-by: Sanyo CapobiangoAnalyzed-by: Justin Pryzby and Alvaro HerreraAuthor: Amit Langote, with a few additional changes by meReviewed-by: Ashutosh BapatBackpatch-through: v11 where partition-wise join was addedDiscussion:https://postgr.es/m/CAO698qZnrxoZu7MEtfiJmpmUtz3AVYFVnwzR%2BpqjF%3DrmKBTgpw%40mail.gmail.com
1 parent0ec2978 commitb10e3bb

File tree

2 files changed

+86
-39
lines changed

2 files changed

+86
-39
lines changed

‎src/backend/optimizer/path/allpaths.c

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -981,42 +981,11 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
981981
Assert(childrel->reloptkind==RELOPT_OTHER_MEMBER_REL);
982982

983983
/*
984-
* Copy/Modify targetlist. Even if this child is deemed empty, we need
985-
* its targetlist in case it falls on nullable side in a child-join
986-
* because of partitionwise join.
987-
*
988-
* NB: the resulting childrel->reltarget->exprs may contain arbitrary
989-
* expressions, which otherwise would not occur in a rel's targetlist.
990-
* Code that might be looking at an appendrel child must cope with
991-
* such. (Normally, a rel's targetlist would only include Vars and
992-
* PlaceHolderVars.) XXX we do not bother to update the cost or width
993-
* fields of childrel->reltarget; not clear if that would be useful.
994-
*/
995-
childrel->reltarget->exprs= (List*)
996-
adjust_appendrel_attrs(root,
997-
(Node*)rel->reltarget->exprs,
998-
1,&appinfo);
999-
1000-
/*
1001-
* We have to make child entries in the EquivalenceClass data
1002-
* structures as well. This is needed either if the parent
1003-
* participates in some eclass joins (because we will want to consider
1004-
* inner-indexscan joins on the individual children) or if the parent
1005-
* has useful pathkeys (because we should try to build MergeAppend
1006-
* paths that produce those sort orderings). Even if this child is
1007-
* deemed dummy, it may fall on nullable side in a child-join, which
1008-
* in turn may participate in a MergeAppend, where we will need the
1009-
* EquivalenceClass data structures.
1010-
*/
1011-
if (rel->has_eclass_joins||has_useful_pathkeys(root,rel))
1012-
add_child_rel_equivalences(root,appinfo,rel,childrel);
1013-
childrel->has_eclass_joins=rel->has_eclass_joins;
1014-
1015-
/*
1016-
* We have to copy the parent's quals to the child, with appropriate
1017-
* substitution of variables. However, only the baserestrictinfo
1018-
* quals are needed before we can check for constraint exclusion; so
1019-
* do that first and then check to see if we can disregard this child.
984+
* We have to copy the parent's targetlist and quals to the child,
985+
* with appropriate substitution of variables. However, only the
986+
* baserestrictinfo quals are needed before we can check for
987+
* constraint exclusion; so do that first and then check to see if we
988+
* can disregard this child.
1020989
*
1021990
* The child rel's targetlist might contain non-Var expressions, which
1022991
* means that substitution into the quals could produce opportunities
@@ -1150,11 +1119,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
11501119
continue;
11511120
}
11521121

1153-
/* CE failed, so finish copying/modifying join quals. */
1122+
/*
1123+
* CE failed, so finish copying/modifying targetlist and join quals.
1124+
*
1125+
* NB: the resulting childrel->reltarget->exprs may contain arbitrary
1126+
* expressions, which otherwise would not occur in a rel's targetlist.
1127+
* Code that might be looking at an appendrel child must cope with
1128+
* such. (Normally, a rel's targetlist would only include Vars and
1129+
* PlaceHolderVars.) XXX we do not bother to update the cost or width
1130+
* fields of childrel->reltarget; not clear if that would be useful.
1131+
*/
11541132
childrel->joininfo= (List*)
11551133
adjust_appendrel_attrs(root,
11561134
(Node*)rel->joininfo,
11571135
1,&appinfo);
1136+
childrel->reltarget->exprs= (List*)
1137+
adjust_appendrel_attrs(root,
1138+
(Node*)rel->reltarget->exprs,
1139+
1,&appinfo);
1140+
1141+
/*
1142+
* We have to make child entries in the EquivalenceClass data
1143+
* structures as well. This is needed either if the parent
1144+
* participates in some eclass joins (because we will want to consider
1145+
* inner-indexscan joins on the individual children) or if the parent
1146+
* has useful pathkeys (because we should try to build MergeAppend
1147+
* paths that produce those sort orderings).
1148+
*/
1149+
if (rel->has_eclass_joins||has_useful_pathkeys(root,rel))
1150+
add_child_rel_equivalences(root,appinfo,rel,childrel);
1151+
childrel->has_eclass_joins=rel->has_eclass_joins;
11581152

11591153
/*
11601154
* Note: we could compute appropriate attr_needed data for the child's
@@ -1167,9 +1161,15 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
11671161
/*
11681162
* If we consider partitionwise joins with the parent rel, do the same
11691163
* for partitioned child rels.
1164+
*
1165+
* Note: here we abuse the consider_partitionwise_join flag by setting
1166+
* it *even* for child rels that are not partitioned. In that case,
1167+
* we set it to tell try_partitionwise_join() that it doesn't need to
1168+
* generate their targetlists and EC entries as they have already been
1169+
* generated here, as opposed to the dummy child rels for which the
1170+
* flag is left set to false so that it will generate them.
11701171
*/
1171-
if (rel->consider_partitionwise_join&&
1172-
childRTE->relkind==RELKIND_PARTITIONED_TABLE)
1172+
if (rel->consider_partitionwise_join)
11731173
childrel->consider_partitionwise_join= true;
11741174

11751175
/*

‎src/backend/optimizer/path/joinrels.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1,
4444
RelOptInfo*rel2,RelOptInfo*joinrel,
4545
SpecialJoinInfo*parent_sjinfo,
4646
List*parent_restrictlist);
47+
staticvoidupdate_child_rel_info(PlannerInfo*root,
48+
RelOptInfo*rel,RelOptInfo*childrel);
4749
staticintmatch_expr_to_partition_keys(Expr*expr,RelOptInfo*rel,
4850
boolstrict_op);
4951

@@ -1312,6 +1314,8 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
13121314
RelOptInfo*joinrel,SpecialJoinInfo*parent_sjinfo,
13131315
List*parent_restrictlist)
13141316
{
1317+
boolrel1_is_simple=IS_SIMPLE_REL(rel1);
1318+
boolrel2_is_simple=IS_SIMPLE_REL(rel2);
13151319
intnparts;
13161320
intcnt_parts;
13171321

@@ -1376,6 +1380,27 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
13761380
AppendRelInfo**appinfos;
13771381
intnappinfos;
13781382

1383+
/*
1384+
* If a child table has consider_partitionwise_join=false, it means
1385+
* that it's a dummy relation for which we skipped setting up tlist
1386+
* expressions and adding EC members in set_append_rel_size(), so do
1387+
* that now for use later.
1388+
*/
1389+
if (rel1_is_simple&& !child_rel1->consider_partitionwise_join)
1390+
{
1391+
Assert(child_rel1->reloptkind==RELOPT_OTHER_MEMBER_REL);
1392+
Assert(IS_DUMMY_REL(child_rel1));
1393+
update_child_rel_info(root,rel1,child_rel1);
1394+
child_rel1->consider_partitionwise_join= true;
1395+
}
1396+
if (rel2_is_simple&& !child_rel2->consider_partitionwise_join)
1397+
{
1398+
Assert(child_rel2->reloptkind==RELOPT_OTHER_MEMBER_REL);
1399+
Assert(IS_DUMMY_REL(child_rel2));
1400+
update_child_rel_info(root,rel2,child_rel2);
1401+
child_rel2->consider_partitionwise_join= true;
1402+
}
1403+
13791404
/* We should never try to join two overlapping sets of rels. */
13801405
Assert(!bms_overlap(child_rel1->relids,child_rel2->relids));
13811406
child_joinrelids=bms_union(child_rel1->relids,child_rel2->relids);
@@ -1417,6 +1442,28 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
14171442
}
14181443
}
14191444

1445+
/*
1446+
* Set up tlist expressions for the childrel, and add EC members referencing
1447+
* the childrel.
1448+
*/
1449+
staticvoid
1450+
update_child_rel_info(PlannerInfo*root,
1451+
RelOptInfo*rel,RelOptInfo*childrel)
1452+
{
1453+
AppendRelInfo*appinfo=root->append_rel_array[childrel->relid];
1454+
1455+
/* Make child tlist expressions */
1456+
childrel->reltarget->exprs= (List*)
1457+
adjust_appendrel_attrs(root,
1458+
(Node*)rel->reltarget->exprs,
1459+
1,&appinfo);
1460+
1461+
/* Make child entries in the EquivalenceClass as well */
1462+
if (rel->has_eclass_joins||has_useful_pathkeys(root,rel))
1463+
add_child_rel_equivalences(root,appinfo,rel,childrel);
1464+
childrel->has_eclass_joins=rel->has_eclass_joins;
1465+
}
1466+
14201467
/*
14211468
* Returns true if there exists an equi-join condition for each pair of
14221469
* partition keys from given relations being joined.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp