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

Commit2cb9ec1

Browse files
committed
Improve inheritance_planner()'s performance for large inheritance sets.
Commitc03ad56 introduced a plannerperformance regression for UPDATE/DELETE on large inheritance sets.It required copying the append_rel_list (which is of size proportional tothe number of inherited tables) once for each inherited table, thusresulting in O(N^2) time and memory consumption. While it's difficult toavoid that in general, the extra work only has to be done forappend_rel_list entries that actually reference subquery RTEs, whichinheritance-set entries will not. So we can buy back essentially all ofthe loss in cases without subqueries in FROM; and even for those, the addedwork is mainly proportional to the number of UNION ALL subqueries.Back-patch to 9.2, like the previous commit.Tom Lane and Dean Rasheed, per a complaint from Thomas Munro.
1 parentda9ee02 commit2cb9ec1

File tree

1 file changed

+96
-20
lines changed

1 file changed

+96
-20
lines changed

‎src/backend/optimizer/plan/planner.c

Lines changed: 96 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,9 @@ inheritance_planner(PlannerInfo *root)
834834
{
835835
Query*parse=root->parse;
836836
intparentRTindex=parse->resultRelation;
837-
Bitmapset*resultRTindexes=NULL;
837+
Bitmapset*resultRTindexes;
838+
Bitmapset*subqueryRTindexes;
839+
Bitmapset*modifiableARIindexes;
838840
intnominalRelation=-1;
839841
List*final_rtable=NIL;
840842
intsave_rel_array_size=0;
@@ -845,6 +847,7 @@ inheritance_planner(PlannerInfo *root)
845847
List*returningLists=NIL;
846848
List*rowMarks;
847849
ListCell*lc;
850+
Indexrti;
848851

849852
Assert(parse->commandType!=CMD_INSERT);
850853

@@ -867,8 +870,10 @@ inheritance_planner(PlannerInfo *root)
867870
* subqueries during planning, and so we must create copies of them too,
868871
* except where they are target relations, which will each only be used in
869872
* a single plan.
873+
*
874+
* To begin with, we'll need a bitmapset of the target relation relids.
870875
*/
871-
resultRTindexes=bms_add_member(resultRTindexes,parentRTindex);
876+
resultRTindexes=bms_make_singleton(parentRTindex);
872877
foreach(lc,root->append_rel_list)
873878
{
874879
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(lc);
@@ -878,12 +883,57 @@ inheritance_planner(PlannerInfo *root)
878883
appinfo->child_relid);
879884
}
880885

886+
/*
887+
* Now, generate a bitmapset of the relids of the subquery RTEs, including
888+
* security-barrier RTEs that will become subqueries, as just explained.
889+
*/
890+
subqueryRTindexes=NULL;
891+
rti=1;
892+
foreach(lc,parse->rtable)
893+
{
894+
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lc);
895+
896+
if (rte->rtekind==RTE_SUBQUERY||
897+
(rte->securityQuals!=NIL&&
898+
!bms_is_member(rti,resultRTindexes)))
899+
subqueryRTindexes=bms_add_member(subqueryRTindexes,rti);
900+
rti++;
901+
}
902+
903+
/*
904+
* Next, we want to identify which AppendRelInfo items contain references
905+
* to any of the aforesaid subquery RTEs. These items will need to be
906+
* copied and modified to adjust their subquery references; whereas the
907+
* other ones need not be touched. It's worth being tense over this
908+
* because we can usually avoid processing most of the AppendRelInfo
909+
* items, thereby saving O(N^2) space and time when the target is a large
910+
* inheritance tree. We can identify AppendRelInfo items by their
911+
* child_relid, since that should be unique within the list.
912+
*/
913+
modifiableARIindexes=NULL;
914+
if (subqueryRTindexes!=NULL)
915+
{
916+
foreach(lc,root->append_rel_list)
917+
{
918+
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(lc);
919+
920+
if (bms_is_member(appinfo->parent_relid,subqueryRTindexes)||
921+
bms_is_member(appinfo->child_relid,subqueryRTindexes)||
922+
bms_overlap(pull_varnos((Node*)appinfo->translated_vars),
923+
subqueryRTindexes))
924+
modifiableARIindexes=bms_add_member(modifiableARIindexes,
925+
appinfo->child_relid);
926+
}
927+
}
928+
929+
/*
930+
* And now we can get on with generating a plan for each child table.
931+
*/
881932
foreach(lc,root->append_rel_list)
882933
{
883934
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(lc);
884935
PlannerInfosubroot;
885936
Plan*subplan;
886-
Indexrti;
887937

888938
/* append_rel_list contains all append rels; ignore others */
889939
if (appinfo->parent_relid!=parentRTindex)
@@ -917,9 +967,29 @@ inheritance_planner(PlannerInfo *root)
917967
/*
918968
* The append_rel_list likewise might contain references to subquery
919969
* RTEs (if any subqueries were flattenable UNION ALLs). So prepare
920-
* to apply ChangeVarNodes to that, too.
970+
* to apply ChangeVarNodes to that, too. As explained above, we only
971+
* want to copy items that actually contain such references; the rest
972+
* can just get linked into the subroot's append_rel_list.
973+
*
974+
* If we know there are no such references, we can just use the outer
975+
* append_rel_list unmodified.
921976
*/
922-
subroot.append_rel_list= (List*)copyObject(root->append_rel_list);
977+
if (modifiableARIindexes!=NULL)
978+
{
979+
ListCell*lc2;
980+
981+
subroot.append_rel_list=NIL;
982+
foreach(lc2,root->append_rel_list)
983+
{
984+
AppendRelInfo*appinfo2= (AppendRelInfo*)lfirst(lc2);
985+
986+
if (bms_is_member(appinfo2->child_relid,modifiableARIindexes))
987+
appinfo2= (AppendRelInfo*)copyObject(appinfo2);
988+
989+
subroot.append_rel_list=lappend(subroot.append_rel_list,
990+
appinfo2);
991+
}
992+
}
923993

924994
/*
925995
* Add placeholders to the child Query's rangetable list to fill the
@@ -933,13 +1003,13 @@ inheritance_planner(PlannerInfo *root)
9331003

9341004
/*
9351005
* If this isn't the first child Query, generate duplicates of all
936-
* subquery RTEs, and adjust Var numbering to reference the
937-
* duplicates. To simplify the loop logic, we scan the original rtable
938-
* not the copy just made by adjust_appendrel_attrs; that should be OK
939-
* since subquery RTEs couldn't contain any references to the target
940-
* rel.
1006+
* subquery(or subquery-to-be)RTEs, and adjust Var numbering to
1007+
*reference theduplicates.To simplify the loop logic, we scan the
1008+
*original rtablenot the copy just made by adjust_appendrel_attrs;
1009+
*that should be OKsince subquery RTEs couldn't contain any
1010+
*references to the targetrel.
9411011
*/
942-
if (final_rtable!=NIL)
1012+
if (final_rtable!=NIL&&subqueryRTindexes!=NULL)
9431013
{
9441014
ListCell*lr;
9451015

@@ -948,14 +1018,7 @@ inheritance_planner(PlannerInfo *root)
9481018
{
9491019
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lr);
9501020

951-
/*
952-
* Copy subquery RTEs and RTEs with security barrier quals
953-
* that will be turned into subqueries, except those that are
954-
* target relations.
955-
*/
956-
if (rte->rtekind==RTE_SUBQUERY||
957-
(rte->securityQuals!=NIL&&
958-
!bms_is_member(rti,resultRTindexes)))
1021+
if (bms_is_member(rti,subqueryRTindexes))
9591022
{
9601023
Indexnewrti;
9611024

@@ -968,7 +1031,20 @@ inheritance_planner(PlannerInfo *root)
9681031
newrti=list_length(subroot.parse->rtable)+1;
9691032
ChangeVarNodes((Node*)subroot.parse,rti,newrti,0);
9701033
ChangeVarNodes((Node*)subroot.rowMarks,rti,newrti,0);
971-
ChangeVarNodes((Node*)subroot.append_rel_list,rti,newrti,0);
1034+
/* Skip processing unchanging parts of append_rel_list */
1035+
if (modifiableARIindexes!=NULL)
1036+
{
1037+
ListCell*lc2;
1038+
1039+
foreach(lc2,subroot.append_rel_list)
1040+
{
1041+
AppendRelInfo*appinfo2= (AppendRelInfo*)lfirst(lc2);
1042+
1043+
if (bms_is_member(appinfo2->child_relid,
1044+
modifiableARIindexes))
1045+
ChangeVarNodes((Node*)appinfo2,rti,newrti,0);
1046+
}
1047+
}
9721048
rte=copyObject(rte);
9731049
ChangeVarNodes((Node*)rte->securityQuals,rti,newrti,0);
9741050
subroot.parse->rtable=lappend(subroot.parse->rtable,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp