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

Commit8d8dcea

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 parent31f3817 commit8d8dcea

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
@@ -1018,42 +1018,11 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
10181018
Assert(childrel->reloptkind==RELOPT_OTHER_MEMBER_REL);
10191019

10201020
/*
1021-
* Copy/Modify targetlist. Even if this child is deemed empty, we need
1022-
* its targetlist in case it falls on nullable side in a child-join
1023-
* because of partitionwise join.
1024-
*
1025-
* NB: the resulting childrel->reltarget->exprs may contain arbitrary
1026-
* expressions, which otherwise would not occur in a rel's targetlist.
1027-
* Code that might be looking at an appendrel child must cope with
1028-
* such. (Normally, a rel's targetlist would only include Vars and
1029-
* PlaceHolderVars.) XXX we do not bother to update the cost or width
1030-
* fields of childrel->reltarget; not clear if that would be useful.
1031-
*/
1032-
childrel->reltarget->exprs= (List*)
1033-
adjust_appendrel_attrs(root,
1034-
(Node*)rel->reltarget->exprs,
1035-
1,&appinfo);
1036-
1037-
/*
1038-
* We have to make child entries in the EquivalenceClass data
1039-
* structures as well. This is needed either if the parent
1040-
* participates in some eclass joins (because we will want to consider
1041-
* inner-indexscan joins on the individual children) or if the parent
1042-
* has useful pathkeys (because we should try to build MergeAppend
1043-
* paths that produce those sort orderings). Even if this child is
1044-
* deemed dummy, it may fall on nullable side in a child-join, which
1045-
* in turn may participate in a MergeAppend, where we will need the
1046-
* EquivalenceClass data structures.
1047-
*/
1048-
if (rel->has_eclass_joins||has_useful_pathkeys(root,rel))
1049-
add_child_rel_equivalences(root,appinfo,rel,childrel);
1050-
childrel->has_eclass_joins=rel->has_eclass_joins;
1051-
1052-
/*
1053-
* We have to copy the parent's quals to the child, with appropriate
1054-
* substitution of variables. However, only the baserestrictinfo
1055-
* quals are needed before we can check for constraint exclusion; so
1056-
* do that first and then check to see if we can disregard this child.
1021+
* We have to copy the parent's targetlist and quals to the child,
1022+
* with appropriate substitution of variables. However, only the
1023+
* baserestrictinfo quals are needed before we can check for
1024+
* constraint exclusion; so do that first and then check to see if we
1025+
* can disregard this child.
10571026
*
10581027
* The child rel's targetlist might contain non-Var expressions, which
10591028
* means that substitution into the quals could produce opportunities
@@ -1187,11 +1156,36 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
11871156
continue;
11881157
}
11891158

1190-
/* CE failed, so finish copying/modifying join quals. */
1159+
/*
1160+
* CE failed, so finish copying/modifying targetlist and join quals.
1161+
*
1162+
* NB: the resulting childrel->reltarget->exprs may contain arbitrary
1163+
* expressions, which otherwise would not occur in a rel's targetlist.
1164+
* Code that might be looking at an appendrel child must cope with
1165+
* such. (Normally, a rel's targetlist would only include Vars and
1166+
* PlaceHolderVars.) XXX we do not bother to update the cost or width
1167+
* fields of childrel->reltarget; not clear if that would be useful.
1168+
*/
11911169
childrel->joininfo= (List*)
11921170
adjust_appendrel_attrs(root,
11931171
(Node*)rel->joininfo,
11941172
1,&appinfo);
1173+
childrel->reltarget->exprs= (List*)
1174+
adjust_appendrel_attrs(root,
1175+
(Node*)rel->reltarget->exprs,
1176+
1,&appinfo);
1177+
1178+
/*
1179+
* We have to make child entries in the EquivalenceClass data
1180+
* structures as well. This is needed either if the parent
1181+
* participates in some eclass joins (because we will want to consider
1182+
* inner-indexscan joins on the individual children) or if the parent
1183+
* has useful pathkeys (because we should try to build MergeAppend
1184+
* paths that produce those sort orderings).
1185+
*/
1186+
if (rel->has_eclass_joins||has_useful_pathkeys(root,rel))
1187+
add_child_rel_equivalences(root,appinfo,rel,childrel);
1188+
childrel->has_eclass_joins=rel->has_eclass_joins;
11951189

11961190
/*
11971191
* Note: we could compute appropriate attr_needed data for the child's
@@ -1204,9 +1198,15 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
12041198
/*
12051199
* If we consider partitionwise joins with the parent rel, do the same
12061200
* for partitioned child rels.
1201+
*
1202+
* Note: here we abuse the consider_partitionwise_join flag by setting
1203+
* it *even* for child rels that are not partitioned. In that case,
1204+
* we set it to tell try_partitionwise_join() that it doesn't need to
1205+
* generate their targetlists and EC entries as they have already been
1206+
* generated here, as opposed to the dummy child rels for which the
1207+
* flag is left set to false so that it will generate them.
12071208
*/
1208-
if (rel->consider_partitionwise_join&&
1209-
childRTE->relkind==RELKIND_PARTITIONED_TABLE)
1209+
if (rel->consider_partitionwise_join)
12101210
childrel->consider_partitionwise_join= true;
12111211

12121212
/*

‎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
staticSpecialJoinInfo*build_child_join_sjinfo(PlannerInfo*root,
4850
SpecialJoinInfo*parent_sjinfo,
4951
Relidsleft_relids,Relidsright_relids);
@@ -1315,6 +1317,8 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
13151317
RelOptInfo*joinrel,SpecialJoinInfo*parent_sjinfo,
13161318
List*parent_restrictlist)
13171319
{
1320+
boolrel1_is_simple=IS_SIMPLE_REL(rel1);
1321+
boolrel2_is_simple=IS_SIMPLE_REL(rel2);
13181322
intnparts;
13191323
intcnt_parts;
13201324

@@ -1379,6 +1383,27 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
13791383
AppendRelInfo**appinfos;
13801384
intnappinfos;
13811385

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

1448+
/*
1449+
* Set up tlist expressions for the childrel, and add EC members referencing
1450+
* the childrel.
1451+
*/
1452+
staticvoid
1453+
update_child_rel_info(PlannerInfo*root,
1454+
RelOptInfo*rel,RelOptInfo*childrel)
1455+
{
1456+
AppendRelInfo*appinfo=root->append_rel_array[childrel->relid];
1457+
1458+
/* Make child tlist expressions */
1459+
childrel->reltarget->exprs= (List*)
1460+
adjust_appendrel_attrs(root,
1461+
(Node*)rel->reltarget->exprs,
1462+
1,&appinfo);
1463+
1464+
/* Make child entries in the EquivalenceClass as well */
1465+
if (rel->has_eclass_joins||has_useful_pathkeys(root,rel))
1466+
add_child_rel_equivalences(root,appinfo,rel,childrel);
1467+
childrel->has_eclass_joins=rel->has_eclass_joins;
1468+
}
1469+
14231470
/*
14241471
* Construct the SpecialJoinInfo for a child-join by translating
14251472
* SpecialJoinInfo for the join between parents. left_relids and right_relids

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp